Josué Martínez Vargas 1 Patrón de diseño Decorator
Patrón de diseño Decorator Descripción Este patrón se utiliza para poder añadir características o funcionalidad a un objeto, en tiempo de ejecución, sin que sea necesario modificar el código existente. Básicamente lo que se hace es envolver el objeto al cual se le quiere extender la funcionalidad, añadiéndole nuevas características. Es por eso que el patrón se llama Decorator, pues eso es precisamente lo que sucede: se decoran los objetos. La gran ventaja de trabajar de esta forma es que las clases que hayan sido creadas previamente no necesitarán ser modificadas para obtener nuevas características.
Código de ejemplo (VB .Net) Clase padre: Es la clase de la cual se va a heredar. Public MustInherit Class Beverage
La descripción será implementada de forma adecuada por cada clase hijo en particular. Dependiendo del tipo de bebida.
Public _description As String = "Unknown beverage"
Public Overridable ReadOnly Property Description() As String Get Return _description End Get End Property El costo será implementado de forma adecuada por cada clase hijo en particular. Dependiendo del tipo de bebida.
Public MustOverride Function Cost() As Double End Class
Clase hijo: Esta es la clase que se va a “decorar” eventualmente. Public Class Espresso Inherits Beverage Public Sub New() _description = "Espresso" End Sub
Cada clase hijo define la descripción en el constructor. En este caso es una bebida Espresso.
Public Overrides Function Cost() As Double Return 1.99 End Function End Class
Cada clase hijo define el costo que le corresponde. En este caso el Espresso vale $1.99.
Josué Martínez Vargas 2 Patrón de diseño Decorator Clase padre decorador: Esta clase también extiende a la clase padre Beverage. Esta debe ser heredada por todas aquellas sub-clases que se vayan a utilizar como decoradores. Public MustInherit Class CondimentDecorator Inherits Beverage Public MustOverride Overrides ReadOnly Property Description() As String End Class
Clase decorador: Esta clase será un decorador y por tanto, extiende a CondimentDecorator. O sea, se utilizará solamente cuando sea necesario añadirle una característica a la clase hijo, que en este caso es Espresso. Mocha será un decorador. En este caso Mocha es un ingrediente que se le puede añadir a la bebida Espresso.
Public Class Mocha Inherits CondimentDecorator
Public _beverage As Beverage Public Sub New(ByVal aBeverage As Beverage) _beverage = aBeverage End Sub Public Overrides Function Cost() As Double Return 0.2 + _beverage.Cost() End Function
Se recibe en el constructor la bebida que será decorada.
Se toma el costo de la bebida que está siendo decorada, y se le suma el costo del Mocha.
Public Overrides ReadOnly Property Description As String Get Return _beverage.Description() & ", Mocha" End Get End Property
Se toma la descripción de la bebida que está siendo decorada y se indica que además tiene Mocha.
End Class
Implementación: Aquí se verá la forma en la cual se utiliza este patrón de diseño con un ejemplo sencillo. Se puede pedir un Espresso con Mocha.
Dim aEspresso As New Espresso Dim mochaDecorator As New Mocha(aEspresso) lblDecorator.Text = mochaDecorator.Description() & " $" & mochaDecorator.Cost()
Esto genera el siguiente resultado: Espresso, Mocha $2.19 O se puede pedir un Espresso simple.
Dim anotherEspresso As New Espresso lblDecorator.Text = anotherEspresso.Description() & " $" & anotherEspresso.Cost()
Esto genera el siguiente resultado: Espresso $1.99
Josué Martínez Vargas 3 Patrón de diseño Decorator Para concluir, algo importante que se presenta en el primer caso, donde se pide un Espresso con Mocha, es que cuando se requiere obtener la descripción y el costo, se utilizan el mochaDecorator.Description() y el mochaDecorator.Cost() respectivamente. Esto se da porque se asume que, si invocamos una función del envoltorio, también será invocada automáticamente la función del objeto que está dentro.