Escolar Documentos
Profissional Documentos
Cultura Documentos
directoryDisplay :=
(TreeDisplay on : treeRoot)
getChildrenBlock:
[mode | node getSubdirectories]
createGraphicNodeBlock:
[:node | node createGraphicNode].
Si está creando una adaptación de interfaz en una clase, este enfoque ofrece
una alternativa conveniente a la subclasificación.
CÓDIGO DE EJEMPLO
Daremos un breve esbozo de la implementación de adaptadores de clases y de
objetos para el ejemplo de la sección de Motivación, comenzando con las clases
Forma y VistaTexto.
daremos un breve esbozo de la implementación de clases y adaptadores de
objetos para el ejemplo de motivación que comienza con la VistaTexto y la forma
de las clases.
class Shape {
public:
Shape();
virtual void BoundingBox(
Point& bottomLeft, Point& topRight
) const;
virtual Manipulator* CreateManipulator() const;
};
class TextView {
public:
TextView();
void GetOrigin(Coordk x, Coord& y) const;
void GetExtent(Coordk width, Coord& height) const;
virtual bool IsEmptyO const;
};
Forma determina sus límites mediante una caja definida por sus esquinas
opuestas. VistaTexto, por el contrario, está definida por un origen, un alto y un
ancho. Forma también define una operación Crear - Manipulador para crear un
Manipulador, el cual sabe cómo mover una forma cuando ésta es manipulada
por el usuario. VistaTexto no tiene una operación equivalente. La clase Forma
Texto es un adaptador entre estas interfaces diferentes.
Un adaptador de clases usa la herencia múltiple para adaptar interfaces. La clave
de los adaptadores de clases es usar una rama de la herencia para heredar la
interfaz y otra para heredar la implementación. La forma normal de hacer esta
distinción en C++ es heredar públicamente la interfaz y privadamente la
implementación.
Usaremos este convenio para definir el adaptador FormaTexto.
class TextShape : public Shape, private TextView {
public:
TextShape();
virtual void BoundingBox(
Point & bottomLeft, Point& topRight
) const;
virtual bool IsEmpty () const;
virtual Manipulator* CreateManipulator() const;
};
La operación CajaLimitrofe convierte la interfaz de VistaTexto para que se ajuste
a la de Forma.
void TextShape::BoundingBox (
Point& bottomLeft, Point& topRight
) const {
Coord bottom, left, width, height;
GetOrigin(bottom, left);
GetExtent(width, height);
_text->GetOrigin(bottom, left);
_text->GetExt ent (width, height) ;
PATRONES RELACIONADOS
El patrón Bridge (141) tiene una estructura similar a un adaptador de objetos,
pero con un propósito diferente: está pensado para separar una interfaz de su
implementación, de manera que ambos puedan cambiar fácilmente y de forma
independiente uno del otro, mientras que un adaptador está pensado para
cambiar la interfaz de un objeto existente.
El patrón Decorator (161) decora otro objeto sin cambiar su interfaz. Un
decorador es por tanto más transparente a la aplicación que un adaptador. Como
resultado, el patrón Decorator permite la composición recursiva, lo que no es
posible con adaptadores puros.
El patrón Proxy (191) define un representante o sustituto de otro objeto sin
cambiar su interfaz.
BRIDGE Estructura de Objetos
(PUENTE)
PROPÓSITO
Desacopla una abstracción de su implementación, de modo que ambas puedan
variar de forma independiente.
TAMBIÉN CONOCIDO COMO
Handle/Body (Manej ador/Cuerpo)
MOTIVACIÓN
Cuando una abstracción puede tener varias implementaciones posibles, la forma
más habitual de dar- les cabida es mediante la herencia. Una clase abstracta
define la interfaz de la abstracción, y las sub- clases concretas la implementan
de distintas formas. Pero este enfoque no siempre es lo bastante flexible. La
herencia liga una implementación a la abstracción de forma permanente, lo que
dificulta modificar, extender y reutilizar abstracciones e implementaciones de
forma independiente.
Pensemos en la implementación de una abstracción portable Ventana en un
toolkit de interfaces de usuario. Esta abstracción debería permitimos escribir
aplicaciones que funcionen, por ejemplo, tanto en el Sistema de Ventanas X
como en Presentation Manager de IBM (PM). Mediante la herencia podríamos
definir una clase abstracta Ventana y subclases VentanaX y VentanaPM que
implementen la interfaz Ventana para las distintas plataformas. Pero este
enfoque tiene dos inconvenientes:
1. No es conveniente extender la abstracción Ventana para cubrir diferentes
tipos de ventanas o nuevas plataformas. Imaginemos una subclase
Ventanalcono, que especializa la abstracción Ventana para representar
iconos. Para admitir este tipo de ventanas en ambas plataformas
debemos implementar dos nuevas clases, VentanalconoX y
VentanalconoPM. Y lo que es peor, tendremos que definir dos clases para
cada tipo de ventana. Dar cabida a una tercera plataforma requeriría otra
nueva subclase de Ventana para cada tipo de ventana.