Download 3.5 Patrones básicos para favorecer la eficiencia, la

Document related concepts
no text concepts found
Transcript
3.5 Patrones básicos para favorecer la
eficiencia, la escalabilidad y el
mantenimiento
Introducción
n
Parámetros en conflicto en todo diseño
n
n
n
n
n
Eficiencia
Mantenimiento
Escalabilidad
Un buen diseño balancea bien los tres parámetros
Patrones
n
n
n
n
Operaciones gruesas (“Fat operations”)
Modelos de objetos gruesos (“Coarse object models”)
Diseño por capas (“Layers”)
Otros
Ejemplo: control de temperatura – descripción (1)
Red de
termostatos
Servidor
Intranet
Aplicación de
administración
Ejemplo: control de temperatura – descripción (y 2)
n
Cada termostato dispone de memoria para
almacenar:
n
n
n
n
Identificador (sólo lectura)
Modelo (sólo lectura)
Temperatura (sólo lectura)
Temperatura nominal (lectura/escritura)
n
n
Cada termostato dispone de un rango válido de valores
Ubicación (lectura/escritura)
IDL para el control de temperatura (1)
module es { module udc { module fbellas { module corbaws {
module idl {
module tcs {
typedef String DeviceIdentifier;
typedef string Model;
typedef short Temperature;
typedef string Location;
exception MalfunctioningException { ... }
exception TemperatureOutOfRangeException { ... }
exception ThermostatNotFoundException { ... }
interface Thermostat {
DeviceIdentifier getDeviceIdentifier()
raises(MalfunctioningException);
Model getModel() raises(MalfunctioningException);
Temperature getTemperature() raises(MalfunctioningException);
Temperature getNominalTemperature() raises(MalfunctioningException);
Location getLocation() raises(MalfunctioningException);
void setNominalTemperature (in Temperature value)
raises(TemperatureOutOfRangeException, MalfunctioningException);
void setLocation(in Location aLocation)
raises(MalfunctioningException);
};
IDL para el control de temperatura (y 2)
interface Controller {
typedef sequence<Thermostat> ThermostatList;
Thermostat findByIdentifier(in DeviceIdentifier identifier)
raises(ThermostatNotFoundException,
MalfunctioningException);
ThermostatList findByLocation(in Location aLocation)
raises(MalfunctioningException);
};
}; }; }; }; }; };
Comentarios
n
Localizar un termostato e imprimir su estado
n
n
6 operaciones remotas (localización + 5 operaciones get)
Demasiadas llamadas remotas
:Console
:Controller
:Thermostat
findByIdentifier()
getDeviceIdentifier()
getModel()
getTemperature()
getNominalTemperature()
getLocation()
Red
Red
(potencialmente)
Operaciones gruesas (1)
struct ThermostatState {
DeviceIdentifier fIdentifier;
Model fModel;
Temperature fTemperature;
Temperature fNominalTemperature;
Location fLocation;
};
interface Thermostat {
ThermostatState getState() raises(MalfunctioningException);
void setNominalTemperature (in Temperature value)
raises(TemperatureOutOfRangeException, MalfunctioningException);
void setLocation(in Location aLocation)
raises(MalfunctioningException);
};
Operaciones gruesas (y 2)
interface Controller {
struct ThermostatListItem {
Thermostat fThermostat;
ThermostatState fState;
};
typedef sequence<ThermostatListItem> ThermostatList;
ThermostatListItem findByIdentifier(in DeviceIdentifier identifier)
raises(ThermostatNotFoundException, MalfunctioningException);
ThermostatList findByLocation(in Location aLocation)
raises(MalfunctioningException);
};
Operaciones gruesas – evaluación (1)
Minimiza el número de invocaciones remotas
n
n
Localizar un termostato e imprimir su estado: 1 invocación remota (si los
objetos Controller y Thermostat están en la misma máquina) o 2 (en
otro caso)
:Console
:ThermostatListItem
:Controller
findByIdentifier()
:Thermostat
getState()
fState.fIdentifier
fState.fModel
fState.fTemperature
fState.fNominalTemperature
fState.fLocation
En la misma máquina virtual
Red
Red
(potencialmente)
Operaciones gruesas – evaluación (2)
n
n
En otras aplicaciones también habrá operaciones set
para dar valor (de golpe) a todos los atributos
modificables
Herencia
<<interface>> 1
Controller
gestiona
*
<<interface>>
Thermometer
getState() : ThermometerState
setLocation(l: Location) : void
<<interface>>
Thermostat
setNominalTemperature(t : Temperature) : void
Operaciones gruesas – evaluación (y 3)
n
Herencia (cont)
n
getState devuelve ThermometerState
n
n
ThermometerState: fIdentifier, fModel,
fTemperature y fLocation
Idealmente nos gustaría definir el struct ThermostatState,
de manera que este último derive del primero y añada
fNominalTemperature
n
n
n
El objeto que implementa Thermostat, devolvería un
ThermostatState
Problema: Un struct no puede heredar de otro
CORBA 2.3 añadió OBV (Objects-By-Value)
n
Permite definir tipos valor con capacidad de herencia
Modelos de objetos gruesos
struct Thermostat {
DeviceIdentifier fIdentifier;
Model fModel;
Temperature fTemperature;
Temperature fNominalTemperature;
Location fLocation;
};
interface Controller {
typedef sequence<Thermostat> ThermostatList;
void setNominalTemperature(in DeviceIdentifier identifier,
in Temperature value) raises(ThermostatNotFoundException,
TemperatureOutOfRangeException, MalfunctioningException);
void setLocation(in DeviceIdentifier identifier, Location aLocation)
raises(ThermostatNotFoundException, MalfunctioningException);
Thermostat findByIdentifier(in DeviceIdentifier identifier)
raises(ThermostatNotFoundException, MalfunctioningException);
ThermostatList findByLocation(in Location aLocation)
raises (MalfunctioningException;
};
Modelos de objetos gruesos – evaluación (1)
n
Minimiza el número de objetos remotos
n
Favorece la escalabilidad
n
n
n
Sin embargo, con cualquiera de los dos diseños anteriores y
haciendo uso de las políticas del POA es posible mantener una
caché de servants (patrón “Evictor”) o implementar todos los
objetos Thermostat (patrón “Default Servant”) con un solo
servant
Minimiza el número de invocaciones remotas
No favorece que los drivers de los termostatos
puedan estar implementados en distintos lenguajes
n
En las soluciones anteriores, los objetos Thermostat eran
objetos CORBA (que potencialmente pueden estar en
procesos distintos e implementados con lenguajes distintos)
Modelos de objetos gruesos – evaluación (y 2)
n
Si existe más de un Controller, el identificador del
termostato no es suficiente
n
n
Herencia
n
n
n
Se precisa también una referencia a su Controller
Se agrava el problema anterior
Posible solución usando OBVs
En general, esta solución es apropiada cuando los
objetos no tienen comportamiento (sólo datos), en
cuyo caso es mejor definirlos como struts (u OBVs)
y no como objetos CORBA
Diseño por capas
Interfaz de usuario
(no CORBA)
Capa de traducción y
delegación (CORBA)
Capa de traducción y
delegación (CORBA)
IDL
Cliente
n
Capa de lógica
de negocio (no CORBA)
Servidor
Capa de delegación y traducción
n
n
Muy pequeña en comparación con el resto del código de la
aplicación
Patrón Adapter
Diseño por capas - ventajas
n
Minimiza errores
n
n
n
n
Especialmente en mappings complejos (ej.: IDL a C++)
Sólo unos pocos miembros del proyecto necesitan
conocer CORBA
La funcionalidad principal de la aplicación se puede
probar de manera aislada de CORBA
Facilita la migración a otro ORB (caso de problemas
de portabilidad) y/o una versión superior
Diseño por capas - inconvenientes
n
Añade más overhead
n
n
Traducción de instancias de tipos generados por el
compilador de IDL a instancias de tipos de más alto nivel y
viceversa
Requiere más código
n
Clases equivalentes a conceptos definidos en IDL
Diseño por capas – Ejemplo
Descripción
n
n
Sólo existen termostatos
El servidor tiene que gestionar termostatos de dos
fabricantes (Acme1 y Acme2)
n
n
Ambos proporcionan software Java para leer y modificar su
estado (paquetes com.acme1.thermostats y
com.acme2.thermostats)
En el futuro puede existir más de un controlador, por
distintos motivos
n
n
Posibles fabricantes que proporcionen software de gestión
de sus termostatos sólo para un lenguaje/plataforma
particular
Escalabilidad
Diseño por capas – Ejemplo
Diagrama de paquetes del software de los fabricantes
com
acme1
acme2
thermostats
thermostats
Diseño por capas – Ejemplo
com::acme1::thermostats y com::acme2::thermostats
Acme1Driver
+
+
+
+
+
+
enable(identifier : String) : void
disable(identifier : String) : void
get(identifier : String, attribute : String) : String
set(identifier : String, attribute : String, value : String) : void
getAllIdentifiers() : String[]
exists(identifier : String) : boolean
Acme2Driver
+
+
+
+
+
+
online(identifier : String) : void
offline(identifier : String) : void
read(identifier : String, attribute : String) : String
write(identifier : String, attribute : String, value : String) : void
getAllIdentifiers() : java::util::Collection
exists(identifier : String) : boolean
Diseño por capas – Ejemplo
Diagrama de paquetes de nuestro software
es::udc::fbellas::corbaws
tcs
thermostats
admin
server
util
shell
server
shell
commands
proxies
idlutil
idl
wrappers
main
CORBA
main
commands
proxies
admin
wrappers
IDL
thermostats
server
exceptions
Diseño por capas – Ejemplo
es::udc::fbellas::corbaws::tcs::idl
<<IDL struct>>
<<IDL interface>>
ThermostatState
Thermostat
<<return>>
+ fIdentifier : DeviceIdentifier
+ fModel : Model
+ getState() : ThermostatState
+ fTemperature : Temperature
+ setNominalTemperature(value : Temperature) : void
+ fNominalTemperature : Temperature
+ setLocation(aLocation : Location) : void
+ fLocation : Location
1
1
<<IDL struct>>
ThermostatListItem
+ fThermostat : Thermostat
+ fstate : ThermostatState
0..n
<<IDL sequence>>
ThermostatList
<<return>>
<<IDL interface>>
Controller
+ findByIdentifier(identifier : DeviceIdentifier) : ThermostatListItem
+ findByLocation(aLocation : Location) : ThermostatList
Diseño por capas – Ejemplo
es::udc::fbellas::corbaws::tcs::idl::Thermostat (1)
#ifndef _es_udc_fbellas_corbaws_tcs_idl_Thermostat_
#define _es_udc_fbellas_corbaws_tcs_idl_Thermostat_
module es { module udc { module fbellas { module corbaws {
module tcs { module idl {
typedef
typedef
typedef
typedef
string DeviceIdentifier;
string Model;
short Temperature;
string Location;
struct ThermostatState {
DeviceIdentifier fIdentifier;
Model fModel;
Temperature fTemperature;
Temperature fNominalTemperature;
Location fLocation;
};
Diseño por capas – Ejemplo
es::udc::fbellas::corbaws::tcs::idl::Thermostat (y 2)
exception MalfunctioningException {
string fExplanation;
};
exception TemperatureOutOfRangeException {
DeviceIdentifier fIdentifier;
Temperature fMinimumTemperature;
Temperature fMaximumTemperature;
Temperature fSelectedTemperature;
};
interface Thermostat {
ThermostatState getState() raises(MalfunctioningException);
void setNominalTemperature(in Temperature value)
raises(TemperatureOutOfRangeException, MalfunctioningException);
void setLocation(in Location aLocation) raises(MalfunctioningException);
};
}; }; }; }; }; };
#endif
Diseño por capas – Ejemplo
es::udc::fbellas::corbaws::tcs::idl::Controller (1)
#ifndef _es_udc_fbellas_corbaws_tcs_idl_Controller_
#define _es_udc_fbellas_corbaws_tcs_idl_Controller_
#include "Thermostat.idl"
module es { module udc { module fbellas { module corbaws {
module tcs { module idl {
struct ThermostatListItem {
Thermostat fThermostat;
ThermostatState fState;
};
typedef sequence<ThermostatListItem> ThermostatList;
exception ThermostatNotFoundException {
string fIdentifier;
};
Diseño por capas – Ejemplo
es::udc::fbellas::corbaws::tcs::idl::Controller (y 2)
interface Controller {
ThermostatListItem findByIdentifier(
in DeviceIdentifier identifier)
raises(ThermostatNotFoundException,
MalfunctioningException);
ThermostatList findByLocation(in Location aLocation)
raises(MalfunctioningException);
};
}; }; }; }; }; };
#endif
Diseño por capas – Ejemplo
es::udc::fbellas::corbaws::tcs::idlutil
n
CommonIDLTypeConversor
n
Clase utilidad con métodos para convertir tipos IDL a Java y
viceversa, comunes a la herramienta de administración y al
servidor
Diseño por capas – Ejemplo
es::udc::fbellas::corbaws::thermostats (1)
<<Interface>>
Driver
DriverManager
+ getModel() : String
- drivers : java.util.Map
+ register(driver : Driver) : void
+ unregister(model : String) : void
1
+ drivers() : java.util.Iterator
+ get(model : String) : Driver
manages
+ create(identifier : String, location : String, nominalTemperature : short) : void
+ destroy(identifier : String)
+ getTemperature(identifier : String) : short
0..n + getNominalTemperature(identifier : String) : short
+ setNominalTemperaure(identifier : String, value : short) : void
+ getLocation(identifier : String) : String
+ setLocation(identifier : String, location : String) : void
+ findAllIdentifiers() : java::util::Collection
+ exists(identifier : String) : boolean
Acme1DriverAdapter
Acme2DriverAdapter
- model : String
- model : String
+ Acme1DriverAdapter()
+ Acme2DriverAdapter()
<<use>>
Acme1Driver
(from thermostats)
<<use>>
Acme2Driver
(from thermostats)
Diseño por capas – Ejemplo
es::udc::fbellas::corbaws::thermostats (y 2)
ThermostatState
-
identifier : String
model : String
temperature : short
nominalTemperature : short
location : String
ThermostatState(identifier : String, model : String, temperature : short, nominalTemperature : short, location : String)
+ getIdentifier() : String
+ getModel() : String
+ getTemperature() : short
+ getNominalTemperature() : short
+ getLocation() : String
+ toString() : String
Diseño por capas – Ejemplo
es::udc::fbellas::corbaws::tcs::server::wrappers (1)
ThermostatPOA
ControllerPOA
ThermostatImpl
- driver : es::udc::fbellas::corbaws::thermostats::Driver
ControllerImpl
- identifier : String
- thermostatImpls : java::util::Map
- model : String
- orb : org::omg::CORBA::ORB
1
0..n
+ ControllerImpl(orb : org::omg::CORBA::ORB)
- nominalTemperature : short
- location : String
+ ThermostatImpl(identifier : String, driver : es::udc::fbellas::corbaws::thermostats::Driver)
<<use>>
<<use>>
DriverManager
<<Interface>>
(from thermostats)
Driver
(from thermostats)
1
Diseño por capas – Ejemplo
es::udc::fbellas::corbaws::tcs::server::wrappers (y 2)
WrappersFacade
+ run(args : String[]) : void
Crea una instancia de "ControllerImpl", la
registra en el servicio de nombres con el
nombre
"es/udc/fbellas/corbaws/tcs/controller",
y se queda escuchando peticiones.
Diseño por capas – Ejemplo
Implementación de es::udc::fbellas::corbaws::tcs::server::wrappers::ThermostatImpl (1)
// ...
ThermostatImpl(String identifier, Driver driver) throws
es.udc.fbellas.corbaws.thermostats.ThermostatNotFoundException,
es.udc.fbellas.corbaws.thermostats.MalfunctioningException {
/* The temperature can not be cached. */
this.driver = driver;
this.identifier = identifier;
model = driver.getModel();
nominalTemperature = driver.getNominalTemperature(identifier);
location = driver.getLocation(identifier);
}
Diseño por capas – Ejemplo
Implementación de es::udc::fbellas::corbaws::tcs::server::wrappers::ThermostatImpl (2)
public ThermostatState getState() throws
es.udc.fbellas.corbaws.tcs.idl.MalfunctioningException {
try {
/* "identifier" and "model" never change. */
ThermostatState state = new ThermostatState();
state.fIdentifier = identifier;
state.fModel = model;
synchronized(this) {
/*
* The temperature is the only attribute that can not be
* cached.
*/
state.fTemperature = driver.getTemperature(identifier);
state.fNominalTemperature = nominalTemperature;
state.fLocation = location;
}
Diseño por capas – Ejemplo
Implementación de es::udc::fbellas::corbaws::tcs::server::wrappers::ThermostatImpl (3)
return state;
} catch (es.udc.fbellas.corbaws.thermostats.MalfunctioningException
e) {
throw CommonIDLTypeConversor.toIDL(e);
} catch (es.udc.fbellas.corbaws.thermostats.
ThermostatNotFoundException e) {
throw new es.udc.fbellas.corbaws.tcs.idl.
MalfunctioningException (e.getMessage());
}
}
Diseño por capas – Ejemplo
Implementación de es::udc::fbellas::corbaws::tcs::server::wrappers::ThermostatImpl (y 4)
public void setNominalTemperature(short value)
throws es.udc.fbellas.corbaws.tcs.idl.TemperatureOutOfRangeException,
es.udc.fbellas.corbaws.tcs.idl.MalfunctioningException {
try {
synchronized(this) {
driver.setNominalTemperature(identifier, value);
nominalTemperature = value;
}
} catch (es.udc.fbellas.corbaws.thermostats.
TemperatureOutOfRangeException e) {
throw CommonIDLTypeConversor.toIDL(e);
} catch (es.udc.fbellas.corbaws.thermostats.
MalfunctioningException e) {
throw CommonIDLTypeConversor.toIDL(e);
} catch (es.udc.fbellas.corbaws.thermostats.
ThermostatNotFoundException e) {
throw new es.udc.fbellas.corbaws.tcs.idl.
MalfunctioningException(e.getMessage());
}
}
Diseño por capas – Ejemplo
Implementación de es::udc::fbellas::corbaws::tcs::idlutil::CommonIDLTypeConversor
// ...
public final static
es.udc.fbellas.corbaws.tcs.idl.MalfunctioningException
toIDL(es.udc.fbellas.corbaws.thermostats.MalfunctioningException e) {
return new es.udc.fbellas.corbaws.tcs.idl.MalfunctioningException(
e.getEncapsulatedException().getMessage());
}
public final static
es.udc.fbellas.corbaws.thermostats.MalfunctioningException
fromIDL(es.udc.fbellas.corbaws.tcs.idl.MalfunctioningException e) {
return new es.udc.fbellas.corbaws.thermostats.MalfunctioningException(
new Exception(e.fExplanation));
}
// ...
Diseño por capas – Ejemplo
Implementación de es::udc::fbellas::corbaws::tcs::server::wrappers::ControllerImpl (1)
class ControllerImpl extends ControllerPOA {
/*
* The methods of this class need not be synchronized because they are
* read-only.
*/
// ...
ControllerImpl(ORB orb) throws IncorrectModelException,
es.udc.fbellas.corbaws.thermostats.ThermostatNotFoundException,
es.udc.fbellas.corbaws.thermostats.MalfunctioningException {
this.orb = orb;
Iterator drivers = DriverManager.drivers();
while (drivers.hasNext()) {
Driver driver = (Driver)drivers.next();
String model = driver.getModel();
Iterator identifiers = driver.findAllIdentifiers().iterator();
while (identifiers.hasNext()) {
String identifier = (String)identifiers.next();
ThermostatImpl thermostatImpl =
new ThermostatImpl(identifier, driver);
thermostatImpls.put(identifier, thermostatImpl);
}
}
}
Diseño por capas – Ejemplo
Implementación de es::udc::fbellas::corbaws::tcs::server::wrappers::ControllerImpl (y 2)
public ThermostatListItem findByIdentifier(String identifier)
throws es.udc.fbellas.corbaws.tcs.idl.ThermostatNotFoundException,
es.udc.fbellas.corbaws.tcs.idl.MalfunctioningException {
ThermostatImpl thermostatImpl =
(ThermostatImpl)thermostatImpls.get(identifier);
if (thermostatImpl == null) {
throw new
es.udc.fbellas.corbaws.tcs.idl.ThermostatNotFoundException(
identifier);
}
return new ThermostatListItem(thermostatImpl._this(orb),
thermostatImpl.getState());
}
// ...
Diseño por capas – Ejemplo
es::udc::fbellas::corbaws::tcs::server::main
Server
<<static>> + main(args : String[]) : void
<<use>>
W rappersFacade
(from wrappers)
Diseño por capas – Ejemplo
es::udc::fbellas::corbaws::tcs::proxies (1)
Controller
ThermostatCollectionItem
- controller : es::udc::fbellas::corbaws::tcs::idl::Controller
- thermostat : Thermostat
- state : ThermostatState
initialize(orb : org::omg::CORBA::ORB)
<<return>>
+ findByLocation(location : String) : Collection
+ findByIdentifier(identifier : String) : ThermostatCollectionItem
ThermostatCollectionItem(thermostat : Thermostat, state : ThermostatState)
+ getThermostat() : Thermostat
+ getState() : ThermostatState
Posee bloque "static"
estático "controller".
1
1
para inicializar el atributo
<<IDL interface>>
ThermostatState
Controller
(from thermostats)
(from idl)
<<return>>
1
Thermostat
AdminIDLTypeConversor
- thermostat : es::udc::fbellas::corbaws::tcs::idl::Thermostat
- identifier : String
- model : String
Thermostat(thermostat : es::udc::fbellas::corbaws::tcs::idl::Thermostat, identifier : String, model : String)
Contiene métodos para convertir desde tipos
de "es::udc::fbellas::corbaws::tcs::idl" a tipos
de "es::udc::fbellas::corbaws::tcs:proxies".
+ getIdentifier() : String
+ getModel() : String
+ getState() : ThermostatState
+ setNominalTemperature(nominalTemperature : short) : void
+ setLocation(location : String) : void
1
<<IDL interface>>
Thermostat
(from idl)
Diseño por capas – Ejemplo
es::udc::fbellas::corbaws::tcs::proxies (y 2)
ProxiesFacade
- orb : org::omg::CORBA::ORB
+ initialize(args : String[]) : void
+ freeResources() : void
<<use>>
Controller
* initialize: inicializa el ORB y el Controller.
* freeResources: destruye el ORB.
Diseño por capas – Ejemplo
Implementación de es::udc::fbellas::corbaws::tcs::proxies::Thermostat
// ...
public es.udc.fbellas.corbaws.thermostats.ThermostatState getState()
throws es.udc.fbellas.corbaws.thermostats.MalfunctioningException,
es.udc.fbellas.corbaws.util.exceptions.InternalErrorException {
try {
return CommonIDLTypeConversor.fromIDL(thermostat.getState());
} catch (es.udc.fbellas.corbaws.tcs.idl.MalfunctioningException e) {
throw CommonIDLTypeConversor.fromIDL(e);
} catch (org.omg.CORBA.SystemException e) {
throw AdminIDLTypeConversor.fromIDL(e);
}
}
// ...
Diseño por capas – Ejemplo
Implementación de es::udc::fbellas::corbaws::tcs::idlutil::CommonIDLTypeConversor
// ....
public final static
es.udc.fbellas.corbaws.thermostats.ThermostatState fromIDL(
es.udc.fbellas.corbaws.tcs.idl.ThermostatState state) {
return new es.udc.fbellas.corbaws.thermostats.ThermostatState(
state.fIdentifier, state.fModel, state.fTemperature,
state.fNominalTemperature, state.fLocation);
}
// ...
Diseño por capas – Ejemplo
es::udc::fbellas::corbaws::util::shell
CommandManager
- commands : java::util::Map
register(command : Command) : void
lookup(commandName : String) : Command
commands() : java::util::Iterator
run(inputStream : java::io::InputStream, printStream : java::io::PrintStream, prompt : String) : void
handles
0..n
<<Interface>>
Command
+ getName() : String
+ getSyntax() : String
+ getExplanation() : String
+ execute(printStream : java::io::PrintStream, args : String[]) : boolean
CommandTemplate
- name : String
- syntax : String
- explanation : String
+ CommandTemplate(name : String, syntax : String, explanation : String)
+ getName() : String
+ getSyntax() : String
+ getExplanation() : String
+ execute(printStream : java::io::PrintStream, args : String[]) : boolean
<<abstract>> # syntaxOK(args : String[]) : boolean
<<abstract>> # processCommand(printStream : java::io::PrintStream, args : String[]) : boolean
# printInvalidSyntax(printStream : java::io::PrintStream) : void
HelpCommand
ExitCommand
HelpCommand()
ExitCommand()
Diseño por capas – Ejemplo
es::udc::fbellas::corbaws::tcs::admin::shell::commands (1)
CommandTemplate
(from shell)
FindByIdentifierCommand
ListCommand
- thermostats : java::util::Map
FindByIdentifierCommand()
+ ListCommand()
FindByLocationCommand
FindByLocationCommand()
SetLocationCommand
SetNominalTemperatureCommand
SetLocationCommand()
SetNominalTemperatureCommand()
<<use>>
0..n
Thermostat
<<use>>
<<use>>
<<use>>
Controller
(from proxies)
<<use>>
(from proxies)
Diseño por capas – Ejemplo
es::udc::fbellas::corbaws::tcs::admin::shell::commands (y 2)
CommandsFacade
+ run(inputStream : java::io::InputStream, printStream : java::io::PrintStream) : void
* Incluye bloque "static" para instanciar todos los comandos y registrarlos en
"es::udc::fbellas::corbaws::util::shell::CommandManager".
* El método "run" invoca a "es::udc::fbellas::corbaws::util::shell::
CommandManager.run(inputStream, printStream, "TCSAdmin> ")".
Diseño por capas – Ejemplo
es::udc::fbellas::corbaws::tcs::admin::shell::main
Console
<<static>> + main(args : String[]) : void
<<use>>
ProxiesFacade
(from proxies)
<<use>>
CommandsFacade
(from commands)
Otras opciones de diseño
n
Caché en cliente
n
n
n
n
Caché en el servidor
Multithreading
n
n
Normalmente cualquier ORB soporta los modelos: pool de threads,
thread por petición y thread por objeto
Distribución en varios servidores (“federation”)
n
n
Problemas de consistencia
Mejor limitarse a cachear estado de objetos pertenecientes al
cliente
Ejs.: servicio de nombres, la práctica, etc.
Usos avanzados del POA
n
Patrón “Evictor”
n
n
Patrón “Default servant”
n
n
Permite implementar una caché de objetos CORBA
Permite implementar múltiples objetos CORBA con un sólo servant en
memoria
Más información en http://www.tic.udc.es/~fbellas/teaching/adoo2000-2001