Resumen de clase. Ejercicio Clientes de una Tarjeta de Crédito (Introducción al Decorator Pattern)



Documentos relacionados
Resumen de clase Ejemplos creacionales. Ideas de Diseño sobre ejercicios anteriores

Patrones Creacionales Builder. Patrones Creacionales Abstract Factory. Patrones Creacionales Singleton. Patrones Creacionales Prototype

En cualquier caso, tampoco es demasiado importante el significado de la "B", si es que lo tiene, lo interesante realmente es el algoritmo.

UNIDAD 1. LOS NÚMEROS ENTEROS.

SOLUCION PARCIAL TASK SCHEDULER. Task Scheduler

Música. Tocar y cantar Autor: Carlos Guido

Tutorial: Cuento Aristotélico

DISERTACION GUSTAVO BRAMBATI

Lección 24: Lenguaje algebraico y sustituciones

Programación Lineal. Ficha para enseñar a utilizar el Solver de EXCEL en la resolución de problemas de Programación Lineal

FORMACIÓN DE EQUIPOS DE E-LEARNING 2.0 MÓDULO DE DISEÑO Y PRODUCCIÓN DE MATERIALES UNIDAD 6 B

CALCULAR NOTAS CON EXCEL

Patterns Iterator / Strategy / Decorator

Sesión 3 - Movimiento Diferencial

GUÍA PARA LA FORMULACIÓN PROYECTOS

Esta extensión está obsoleta a partir de PHP 5.5.0, y será eliminada en el futuro

Transcripción entrevista Carlos. Entrevistadora: entonces tu lengua materna es náhuatl? Entrevistado: sí, náhuatl.

UTILIZACIÓN DE UNA CUENTA DE CORREO ELECTRÓNICO (NUEVO) Acceso al correo electrónico

1

Análisis de esquemas XML [1]

Tema 07. LÍMITES Y CONTINUIDAD DE FUNCIONES

COLEGIO APUNTES ACCESS

7. VLSM. IST La Recoleta

3º Grado Educación Infantil Bilingüe Números. Método Singapur y F. Bravo E R

PREGUNTAS FRECUENTES Nuevo Plan de Jubilación a Partir del 1º de Julio del 2014

Mejorando las ventas utilizando el conocimiento sobre nuestros clientes

Fundamentos de Investigación de Operaciones Investigación de Operaciones 1

Estrategias de producto y precio

GUÍA TÉCNICA PARA LA DEFINICIÓN DE COMPROMISOS DE CALIDAD Y SUS INDICADORES

UNIDAD 6. POLINOMIOS CON COEFICIENTES ENTEROS

5.1. Organizar los roles

Tutorial de Subneteo Clase A, B, C - Ejercicios de Subnetting CCNA 1

Conceptos. ELO329: Diseño y Programación Orientados a Objetos. ELO 329: Diseño y Programación Orientados a Objetos

El Instituto Electoral del Estado de Campeche (IEEC), es responsable de organizar las elecciones locales en el Estado.

Lección 4: Suma y resta de números racionales

MATERIA: DISCAPACIDAD E INTEGRACIÓN

LABORATORIO Nº 2 GUÍA PARA REALIZAR FORMULAS EN EXCEL

CASO PRÁCTICO DISTRIBUCIÓN DE COSTES

Ética en la Investigación con seres humanos. Mod. 3 UD4: La investigación con datos personales

Familias inmigrantes Nos vamos a ir a otro país, cómo se lo explico?

Eduardo Kido 26-Mayo-2004 ANÁLISIS DE DATOS

Interpolación polinómica

Actividad 2.- Cuento y vídeo de Ubuntu

Fundamentos de negocio Recursos Humanos > Problemas con tu personal?: Aprende a resolverlos (Manejo de conflictos) > Gana negociando

SGIC. Propuesta para Plan de Telefonía y Perfiles de Consumo

MÉTODO DEL CAMBIO DE BASE PARA CÁLCULO MANUAL DE SUBREDES CON IP V4.0

Institución Educativa Inem Felipe Pérez de Pereira 2012 Estrategia taller. AREA: Sistemas de información Taller Previsto

Apuntes de Matemática Discreta 1. Conjuntos y Subconjuntos

VENTAJAS Y DESVENTAJAS DE LAS TECNOLOGIAS

Programación Orientada a Objetos en Java

Guía de seguridad de Facebook

Tutorial de Subneteo Clase A, B - Ejercicios de Subnetting CCNA 1

MEDICION DE LA CREACIÓN DE VALOR ECONOMICO EN LA EMPRESA

Lección 9: Polinomios

Colegio Salesiano Don Bosco Academia Reparación Y Soporte Técnico V Bachillerato Autor: Luis Orozco. Subneteo

PRÁCTICAS DE GESTIÓN GANADERA:

Título: Educar para fabricar ciudadanos emisión 49 (13/12/2009, 21:00 hs) temporada 14

Mindfulness, o la meditación occidental

PARA COMERCIANTES Y AUTÓNOMOS. INFORMACIÓN SOBRE TARJETAS DE CRÉDITO.

Colegio Alexander von Humboldt - Lima. Tema: La enseñanza de la matemática está en un proceso de cambio

Las normas de casa: todos aportamos y todos las respetamos. Tener claras las cosas que vuestra hija o hijo no puede hacer es muy 1

Luis Eduardo Barón Bienvenidos al Módulo N. 3 de Internet Para Emprendedores. Yo soy Luis Eduardo Barón. Álvaro Mendoza Y yo soy Álvaro Mendoza.

CONCLUSIONES TALLERES

TÉCNICAS DE ESTUDIO EN EL TERCER CICLO DE EDUCACIÓN PRIMARIA

SIFAC II Respuesta a Consultas de las Empresas Sanitarias

MANEJANDO FICHEROS Y CARPETAS

Cómo las herramientas en línea están revolucionando la implementación de ITIL e ISO 20000

Región de Murcia Consejería de Educación, Ciencia e Investigación. Manual Usuario FCT

CURSO INSTALACION E IMPLEMENTACION ALOJA SOFTWARE HOTEL MODULO 02: Datos Adicionales de configuración [1]

Tutorial de UML. Introducción: Objetivos: Audiencia: Contenidos:

Entrevistadora: entonces el español lo aprendiste en la escuela y el ngigua en la casa

Ejemplos de conversión de reales a enteros

Conclusiones. Particionado Consciente de los Datos

PROCEDIMIENTO DE ENVÍO DE PLANILLAS A TURISTOUR

Es una persona que ayudará a que los derechos de las personas con discapacidad se hagan realidad

Evaluación de sus Habilidades Comerciales

TE GUSTARÍA CONTAR CON LA MEJOR HERRAMIENTA PARA HACER MARKETING POR INTERNET?

Programa para el Mejoramiento de la Enseñanza de la Matemática en ANEP Proyecto: Análisis, Reflexión y Producción. Fracciones

Política de Privacidad del Grupo Grünenthal

RESUMEN. Colegio Antonio Machado Baeza (Jaén)

5. PRESUPUESTO (GASTOS)

Operativa en Acciones: Introducción a la Bolsa

Descomposición factorial de polinomios

GUÍA PARA MANEJAR GOOGLE DRIVE

Impress : Programa de presentaciones de OpenOffice.

Tienda Virtual Synergy (Parte 2)

Aviso de Privacidad. Aviso de Privacidad de GRUPO EMPRESARIAL DASCLEAN DE MEXICO, S.A. DE C.V.

DISENO DE CURSOS AUTOGESTNOS. Mana del Socorro Perez Alcala

2.2.- Paradigmas de la POO

**NOTA** las partes tachadas todavía no están escritas, se ira actualizando poco a poco el documento

Educar en casa Promover su autonomía

DUDAS DE ACCESO / PROBLEMAS DE ACCESO MÁS FRECUENTES

COMO AUMENTAR MIS VENTAS: ENFOQUE EN PROMOCION Y PUBLICIDAD

Plan de clase (1/4) Intenciones didácticas: Que los alumnos reflexionen sobre la manera de ubicar puntos en el plano cartesiano.

Pero para ello tenemos que cumplir ciertas normas. Para poder usar esta tecnología tendremos que cumplir con los siguientes requisitos.

William Shakespeare. Es el destino quien baraja las cartas pero nosotros somos los que jugamos

La Zona de Desarrollo Próximo (ZDP)

Congreso de Colegios Católicos, Una pasión que se renueva. Pontificia Universidad Católica de Chile. Septiembre 2015.

ENTÉRESE! AQUÍ MISMO: TODO SOBRE MARCAS SE HAN FIJADO CUÁNTAS MARCAS? TODO EN EL MUNDO ES MARCAS! TODO!

Itinerario Formativo en Innovación Docente

Transcripción:

Resumen de clase Ejercicio Clientes de una Tarjeta de Crédito (Introducción al Decorator Pattern) 2 cuatrimestre 2008

Contenido ENUNCIADO...3 SOBRE EL DOMINIO...3 SOLUCIÓN...4 DE QUÉ LADO CAE LA PELOTA?...4 1) EL IF NUESTRO DE CADA DÍA...4 2) SUBCLASIFICAR...6 3) TENER UNA COLECCIÓN DE CONDICIONES COMERCIALES...7 4) CAMBIANDO EL ÁNGULO DE LA INFORMACIÓN...8 EL DECORATOR DE LIBRO...13 METÁFORA ASOCIADA AL DECORATOR...14 5) UN POCO DE TODO...15 LO QUE APRENDIMOS: UNA NUEVA IDEA...16 2

Enunciado Pertenecemos a la gerencia de Condiciones Comerciales de una empresa emisora de una Tarjeta de Crédito. La gerencia de Ventas nos provee una interfaz Cliente, cuyos contratos son: comprar(int monto) pagarvencimiento(int monto) cd Clientes de una Tarjeta de Crédito «interface» Cliente ClientePosta (de Ventas) Se pide contemplar los siguientes requerimientos: algunos clientes adheridos a una promoción suman 15 puntos por cada compra mayor a $ 50. además, algunos clientes contrataron el sistema 'Safe Shop', que bloquea compras de la tarjeta mayores a un monto que el cliente fija. Sobre el dominio Tenemos dos sectores dentro de la empresa de tarjetas de crédito: Ventas Condiciones Comerciales Qué responsabilidades cumplen cada una? Si bien la empresa tiene vendedores que son quienes interactúan en muchos casos con los clientes (para ofrecer nuevos servicios), en muchas empresas existe un sector que determina restricciones o acuerdos que los vendedores deben cumplir, que son las condiciones comerciales. Ejemplos: Todos los clientes del exterior tienen un descuento por pronto pago del 20% Sólo se puede trabajar con clientes mayoristas Los clientes Rabufetti y Conesa aceptan cheques a 30, 60 y 90 días como forma de pago Condiciones comerciales Ventas Vemos que Cliente intersecta el negocio de ambos sectores (Ventas y Condiciones Comerciales). Ahora veremos cómo atacar estos requerimientos. 3

Solución De qué lado cae la pelota? Aquí vemos que los requerimientos que se agregan corresponden a condiciones comerciales de cada venta, pero que también aparece en juego una cuestión política: si la Gerencia de Ventas quiere auditar los cambios en la clase Cliente, porque es de Ventas 1, aparecen restricciones que limitan mi solución final. Para el resto del ejercicio vamos a suponer que yo sí puedo modificar la clase Cliente, y vamos a pensar en alternativas de diseño. 1) El if nuestro de cada día Si aprovechamos el consejo de ir por lo más simple bueno, lo más sencillo es modificar la clase cliente: Necesitamos saber si el cliente está adherido a la promoción, cuál es el monto mínimo y los puntos que se le otorgan Necesitamos conocer si el cliente está adherido al sistema Safe Shop y cuál es el monto máximo de compra Hacemos los cambios pertinentes: 1 Asociar una clase a una persona o grupo de desarrolladores (lo que en la jerga de Sistemas se llama armar una quinta ) también recibe el nombre code ownership: pensar en que el código tiene un dueño. El primer impacto negativo es fácil de apreciar: si me cuesta modificar la clase Cliente, ya no pienso en la simplicidad como cualidad de diseño de mi solución sino en no verme comprometido a cambiar el Cliente. Además genera numerosos recelos entre equipos de Ventas y Condiciones Comerciales. 4

cd Clientes de una Tarjeta de Crédito ClientePosta (de Ventas) «interface» Cliente - montominimopromocion: int - tienepromocion: boolean - puntospremiopromocion: int - puntosacumulados: int - usasafeshop: boolean - montomaximosafeshop: int El código de ClientePosta queda: if (this.usasafeshop && monto > this.montomaximosafeshop) { throw new BusinessException("Ha excedido el monto maximo"); if (this.tienepromocion && monto > MONTO_MINIMO_PROMOCION) { this.puntosacumulados += PUNTOS_PREMIO_PROMOCION;... Podemos evitar el atributo usasafeshop convirtiéndolo en un método: if (this.usasafeshop() && monto > this.montomaximosafeshop) {... // Si el monto máximo es cero no usa Safe Shop public boolean usasafeshop() { return this.montomaximosafeshop > 0; Ok, esta solución tiene algunos inconvenientes: Ensucia la lógica del método comprar() cliente Agrega atributos que no todos los clientes necesitan: si el cliente no se adhiere a la promoción no necesita tener puntosacumulados. El problema no es guardar una referencia de más, sino que el que lee la clase Cliente puede confundirse pensando que esa variable la necesita el cliente (esté o no en promoción). Por otra parte es fácil hacer que el cliente entre y salga de la promoción de puntos o habilite/deshabilite la opción Safe Shop. Como los requerimientos son más bien simples de codificar, agregar un if es una opción más que posible. Si para calcular los puntos acumulados necesitara una lógica más compleja o bien si aparecieran muchas más condiciones comerciales quizás podría empezar a molestarme la cantidad de líneas agregadas en esos ifs. 5

2) Subclasificar Otra opción es subclasificar el concepto ClientePosta. Tenemos así dos subclases: ClienteSafeShop y ClientePromocion. cd Solución - Subclasificación «interface» Cliente ClientePosta (de Ventas) ClientePromocion - montominimo: int - puntosacumulados: int - puntospremio: int ClienteSafeShop - montomaximo: int En ClienteSafeShop tenemos: if (monto > this.montomaximo) { throw new BusinessException("Ha excedido el monto maximo"); super.comprar(monto); En ClientePromocion tenemos: super.comprar(monto); if (monto > MONTO_MINIMO) { this.puntosacumulados += PUNTOS_PREMIO; Esta alternativa separa claramente las responsabilidades de cada condición comercial. Ya no se ensucia al ClientePosta, sino que cada subclase delega en la superclase el comportamiento default 6

del comprar y además hace su propio agregado. Parece una trivialidad pero no lo es, el atributo montomaximosafeshop pasa a llamarse montomaximo a secas. No obstante esta opción presenta una clara desventaja: no sólo es complicado hacer que un cliente posta habilite/deshabilite el servicio de Safe Shop: esta solución no permite que coexistan un cliente en promoción que también tenga safe shop, y es el motivo que lo convierte en la solución menos deseable de todas. 3) Tener una colección de condiciones comerciales Para esto necesitamos entender que queremos separar dos conceptos que no son intrínsecos: El cliente en sí (representado por la clase ClientePosta) Las condiciones comerciales del cliente, que pueden ser muchas y además las quiero combinar Algo así: cd Solución - Condiciones comerciales como Strategies «interface» Cliente ClientePosta (de Ventas) -condicionescomerciales * CondicionComercial SafeShop Promocion - montomaximo: int - puntosacumulados: int - montominimo: int - puntospremio: int Qué tipo de colección voy a usar para las condiciones comerciales? Y no me da lo mismo si sumo los puntos y resulta que salta la alarma de Safe Shop. Como además no quiero tener dos veces a la condición comercial Safe Shop, entonces el ClientePosta usará un set ordenado de condiciones comerciales. Esta alternativa toma como propias las ventajas de las soluciones anteriores: Separa el comportamiento propio de cada condición comercial Es fácil agregar o sacar una condición comercial dinámicamente: basta con actualizar la lista de condiciones comerciales del ClientePosta 7

El código de ClientePosta cambia a: for (CondicionComercial condicion : this.condicionescomerciales) { condicion.comprar(monto);... En ClienteSafeShop tenemos: if (monto > this.montomaximo) { throw new BusinessException("Ha excedido el monto maximo"); En ClientePromocion tenemos: if (monto > MONTO_MINIMO) { this.puntosacumulados += PUNTOS_PREMIO; La desventaja es que tengo que asegurarme de cumplir el orden de las condiciones comerciales para que no tenga efectos colaterales: no me da lo mismo que esté primero safe shop y después promoción que viceversa 4) Cambiando el ángulo de la información Dos cosas interesantes para comentar: 8

Revisemos el código del ClientePosta nuevamente: for (CondicionComercial condicion : this.condicionescomerciales) { condicion.comprar(monto);... Fíjense que primero enviamos el mensaje comprar() a las condiciones comerciales porque la opción Safe Shop hace que yo tenga que cortar la compra. Si algunas condiciones comerciales trabajaran después de cada compra, entonces tendría que tener dos listas, una de pre-condiciones y otra de post-condiciones. Las condiciones comerciales definen un comportamiento polimórfico con respecto al ClientePosta (a ambos les puedo enviar un mensaje comprar()). Si bien no tiene gracia reemplazar al ClientePosta con un ClienteSafeShop, eso puede abrirnos una puerta para ver otra solución posible Si el ClientePosta y el ClienteSafeShop / ClientePromocion son polimórficos en el contexto en que el cliente compra: cd Clientes de una Tarjeta de Crédito «interface» Cliente ClientePosta (de Ventas) * CondicionComercial Qué tal si cambiamos la óptica? O sea: que la condición comercial sea quien conozca al ClientePosta. Pero ya no estamos modelando una condición comercial, sino un Cliente con comportamiento agregado: 9

cd Solución - Decorando clientes «interface» Cliente ClientePosta (de Ventas) -cliente 1 ClienteConCondicionComercial ClientePromocion - montominmo: int - puntosacumulados: int - puntospremio: int ClienteSafeShop - montomaximo: int Este modelo así tiene una contra importante que ya vimos en la solución 2: no me permite que un cliente en Promoción se asocie al sistema Safe Shop. Pero podemos ajustar eso con un detalle: el ClienteCondicionComercial puede conocer un Cliente en lugar de conocer al ClientePosta: cd Solución - Decorando clientes «interface» Cliente 1 -cliente ClientePosta (de Ventas) ClienteConCondicionComercial ClientePromocion - montominmo: int - puntosacumulados: int - puntospremio: int ClienteSafeShop - montomaximo: int 10

Y lo que estamos haciendo con el cliente es decorándolo (vamos agregando comportamiento cuando compra). Veamos cómo cambia el código en el caso del ClienteSafeShop: if (monto > this.montomaximo) { throw new BusinessException("Ha excedido el monto maximo"); this.cliente.comprar(monto); Y el del ClientePromocion: this.cliente.comprar(monto); if (monto > MONTO_MINIMO) { this.puntosacumulados += PUNTOS_PREMIO; El cliente es un delegado: no sabemos si será el ClientePosta o alguno de los clientes que tengan condiciones comerciales. Sobre la solución podemos decir: El comprar de Safe Shop primero valida que no exceda el máximo de la compra y después delega al cliente, mientras que el ClientePromocion delega primero y después acumula los puntos, lo cual permite que la regla de negocio comprar falle y no se acumulen los puntos erróneamente. Esto es una ventaja respecto a la solución 3): podemos agregar comportamiento antes o después de la compra. Una consecuencia es que esta solución no requiere un orden específico de las condiciones comerciales: puedo tener primero la promoción y después el safe shop o al revés y la solución sigue funcionando correctamente (no suma puntos si no corresponde, primero se delega el control al safe shop). El ClientePosta (de Ventas) no se ve afectado. Esto puede verse como una ventaja, ya que estoy agregando comportamiento a un objeto sin cambiarle una línea de código. Cada condición comercial es un decorador del cliente en el sentido en que es quien agrega comportamiento. El cliente es el decorado o componente. Un cliente Safe Shop se representa así: cd Decorando clientes :ClienteSafeShop :ClientePosta (de Ventas) Un cliente con Safe Shop y Promoción se representa así: cd Decorando clientes :ClienteSafeShop :ClientePromocion :ClientePosta (de Ventas) En este ejemplo no parece tener mucho sentido, pero puedo intercambiar decoradores 11

cd Decorando clientes :ClienteSafeShop :ClientePromocion :ClientePosta (de Ventas) o bien cd Decorando clientes :ClientePromocion :ClienteSafeShop :ClientePosta (de Ventas) Una desventaja de esta solución es que me obliga a implementar un método pagarvencimiento() que simplemente delega al cliente la resolución: En ClienteCondicionComercial public void pagarvencimiento(int monto) { this.cliente.pagarvencimiento(monto); Entonces para usar esta idea, lo que conviene es que el Componente tenga una interfaz chica (reducida en cantidad de métodos): Decorator Decorator Decorator Componente Tanto la técnica de decoración como la del Strategy nos permite agregar comportamiento en forma dinámica. La diferencia es que el Strategy trabaja desde el cliente hacia adentro y que el Decorator (así es el nombre del pattern) trabaja agregando pieles desde el objeto hacia fuera: Decorator Strategy cd Decorando clientes :ClienteSafeShop :ClientePromocion :ClientePosta (de Ventas) 12

Esto trae consecuencias importantes: en mi aplicación tengo que instanciar Clientes decorados en lugar del ClientePosta, mientras que con la solución 3) el cliente conservaba su identidad (seguía siendo él). Entonces hay que tener cuidado cuando pregunto si dos clientes son los mismos (el decorado no es el componente). cómo sería cómodo instanciar un cliente con SafeShop? Quizás estaría bueno poder pasarle el delegado en el constructor mismo: Cliente bertolini = new ClienteSafeShop(new Cliente("bertolini"), 100); Cliente amalita = new ClienteSafeShop( new ClientePromocion(new Cliente("amalita")), 160); El Decorator de Libro Intent: "Attach additional responsibilities to an object dynamically. Decorators provide a flexible alternative to subclassing for extending functionality." 13

Metáfora asociada al Decorator La matrioshka 14

5) Un poco de todo Ahora, si yo tengo los clientes decorados y quiero eliminar el servicio Safe Shop. Cómo hago? Como el Decorator me permite anidar decoraciones, no tengo idea si el Safe Shop va primero o después que los otros decoradores. Una solución posible es tener dos tipos de clientes: Los clientes posta Los que usan condiciones comerciales Es decir, decoramos al cliente posta con uno que tenga las condiciones comerciales (juntamos la solución 3 con la 4): cd Clientes de una Tarjeta de Crédito «interface» Cliente 1 ClientePosta (de Ventas) ClienteDecorado CondicionComercial * Promocion SafeShop - puntosacumulados: int - montominimo: int - puntospremio: int - montomaximo: int Esta solución comparte la desventaja de la alternativa 3: si determinadas condiciones comerciales actúan antes de la compra y otras después, debemos considerar tener dos métodos para cada condición comercial: doprecomprar(int monto) y dopostcomprar(int monto). Entonces en el cliente decorado activaríamos las condiciones comerciales antes y después de delegar la compra al cliente: for (CondicionComercial condicion : this.condicionescomerciales) { condicion.doprecomprar(monto); this.cliente.comprar(monto); for (CondicionComercial condicion : this.condicionescomerciales) { condicion.dopostcomprar(monto); 15

Y en Safe Shop y Promocion redefinimos los métodos que nosotros queremos: >>SafeShop public void doprecomprar(int monto) { if (monto > this.montomaximo) { throw new BusinessException("Ha excedido el monto maximo"); >>Promocion public void dopostcomprar(int monto) { if (monto > MONTO_MINIMO) { this.puntosacumulados += PUNTOS_PREMIO; Lo que aprendimos: una nueva idea El Decorator propone una alternativa distinta a lo que anteriormente veníamos trabajando: interponer a un objeto entre el que pide una cosa y el que la resuelve. Decorator de Cliente Un objeto que envía el mensaje comprar() Cliente Posta En el Decorator, el chiste está en que el decorado no se entera que lo decoran y tampoco el que envía el mensaje comprar(), porque el decorador y el componente son polimórficos. Otra idea de diseño similar ocurre cuando hay incompatibilidades entre quien envía el mensaje y quien lo resuelve, ya sea: Porque el objeto posta tiene un mensaje con nombre diferente Porque el objeto posta necesita más información Porque queremos ofrecer una forma más cómoda de usar al objeto posta Entonces lo que sucede es que en cualquiera de esos casos no me sirve tener objetos polimórficos, pero sí me sirve la misma idea de tener un intermediario que corrija esa interferencia para que el mensaje pueda llegar correctamente al objeto que lo tiene que responder 2 : 2 Para mayor referencia véase el pattern Adapter (139) en Design Patterns: Elements of Reusable Object- Oriented Software, de Gamma, Helm, Johnson y Vlissides, Addison-Wesley Professional Computing Series, 1994 16

Un objeto que envía un mensaje Integer amount =...; object.buy(amount); Adaptador public void buy(integer amount) { realobject.comprar(amount.intvalue()); Objeto Posta que resuelve el mensaje public void comprar(int monto) Haya o no polimorfismo, en ambos casos se envuelve a un objeto para agregar o cambiar comportamiento. El objeto original no cambia su funcionalidad y aquí está el concepto nuevo: hay un intermediario que delega al objeto original y el que envía el mensaje (el objeto cliente o requirente ) ya no habla con el objeto posta sino con este intermediario. 17