This shows you the differences between two versions of the page.
wiki:pdd_7 [2024/09/02 00:14] – created admin | wiki:pdd_7 [2024/09/08 22:52] (current) – admin | ||
---|---|---|---|
Line 1: | Line 1: | ||
====== Decorator ====== | ====== Decorator ====== | ||
+ | **Contexto**: | ||
+ | |||
+ | **Problema**: | ||
+ | |||
+ | * TCPZipChannel extends TCPChannel | ||
+ | * TCPBufferedChannel extends TCPChannel | ||
+ | * TCPBufferedZipChannel extiende TCPZipChannel extends TCPChannel | ||
+ | * TCPLogChannel extends TCPChannel | ||
+ | * TCPLogBufferedZipChannel extends TCPBufferedZipChannel extends TCPZipChannel extends TCPChannel | ||
+ | * UDPZipChannel extends UDPChannel | ||
+ | * UDPBufferedChannel extends UDPChannel | ||
+ | * UDPBufferedZipChannel extends UDPZipChannel extends UDPChannel | ||
+ | * UDPLogChannel extends UDPChannel | ||
+ | * UDPLogBufferedZipChannel extends UDPBufferedZipChannel extends UDPZipChannel extends UDPChannel | ||
+ | |||
+ | En esta solución, usamos la herencia para implementar subclases para cada conjunto de funcionalidades. Supongamos que el usuario necesita un canal UDP con buffer y compresión. Para ello, tuvimos que implementar '' | ||
+ | |||
+ | **Solución**: | ||
+ | |||
+ | En nuestro problema, al optar por decoradores, | ||
+ | |||
+ | <code java> | ||
+ | channel = new ZipChannel(new TCPChannel()); | ||
+ | // TCPChannel que comprime/ | ||
+ | |||
+ | channel = new BufferChannel(new TCPChannel()); | ||
+ | // TCPChannel con un buffer asociado | ||
+ | |||
+ | channel = new BufferChannel(new UDPChannel()); | ||
+ | // UDPChannel con un buffer asociado | ||
+ | |||
+ | channel= new BufferChannel(new ZipChannel(new TCPChannel())); | ||
+ | // TCPChannel con compresión y un buffer asociado | ||
+ | |||
+ | </ | ||
+ | |||
+ | Por lo tanto, en una solución con decoradores, | ||
+ | |||
+ | Falta entonces explicar las clases que son los decoradores propiamente dichos, como '' | ||
+ | |||
+ | |||
+ | <code java> | ||
+ | class ChannelDecorator implements Channel { | ||
+ | |||
+ | private Channel channel; | ||
+ | |||
+ | public ChannelDecorator(Channel channel) { | ||
+ | this.channel = channel; | ||
+ | } | ||
+ | |||
+ | public void send(String msg) { | ||
+ | channel.send(msg); | ||
+ | } | ||
+ | |||
+ | public String receive() { | ||
+ | return channel.receive(); | ||
+ | } | ||
+ | |||
+ | } | ||
+ | </ | ||
+ | |||
+ | Esta clase tiene dos características importantes: | ||
+ | |||
+ | * Es un '' | ||
+ | * Posee internamente un objeto del tipo '' | ||
+ | |||
+ | Por último, llegamos a los decoradores reales. Estos son subclases de '' | ||
+ | |||
+ | <code java> | ||
+ | class ZipChannel extends ChannelDecorator { | ||
+ | |||
+ | public ZipChannel(Channel c) { | ||
+ | super(c); | ||
+ | } | ||
+ | |||
+ | public void send(String msg) { | ||
+ | " | ||
+ | super.send(msg); | ||
+ | } | ||
+ | |||
+ | public String receive() { | ||
+ | String msg = super.receive(); | ||
+ | " | ||
+ | return msg; | ||
+ | } | ||
+ | |||
+ | } | ||
+ | </ | ||
+ | |||
+ | Para entender el funcionamiento de '' | ||
+ | |||
+ | <code java> | ||
+ | Channel c = new ZipChannel(new TCPChannel()); | ||
+ | c.send(" | ||
+ | </ | ||
+ | |||
+ | La llamada a send en la última línea del ejemplo desencadena las siguientes ejecuciones de métodos: | ||
+ | |||
+ | * Primero, se ejecuta ZipChannel.send, | ||
+ | * Después de la compresión, | ||
+ | * ChannelDecorator.send simplemente transfiere la llamada al Channel que referencia, que en este caso es un TCPChannel. | ||
+ | * Finalmente, llegamos a TCPChannel.send, |