Implementación Decorator Pattern - lenoryv/Design-Patterns GitHub Wiki
Basándonos en la estructura del patrón Decorator , decoremos nuestro helado. Apliquemos el patrón del decorador para resolver el problema de nuestra heladería y agreguemos un par de funciones para convertirlo en un ejemplo completo.
Como puede ver, ToppingDecortor tiene el tipo IceCream como Componente, que es IceCream , también HoneyToppingDecorator y NutsToppingDecorator tienen una referencia al objeto de IceCream . Los decoradores tienen operaciones adicionales que realizar.
Aquí tenemos un completo programa de trabajo basado en el UML de la heladería después de aplicar el patrón decorador.
La clase IceCream es una clase abstracta con la función abstracta getDescription() , por lo que cualquier otra clase que la herede tiene que implementarla.
clase abstracta IceCream {
abstract fun getDescription (): String
} clase VanillaIceCream : IceCream () {
anular diversión getDescription () = "Helado de vainilla"
} clase StrawberryIceCream : IceCream () {
anular diversión getDescription () = "Helado de fresa"
} class ChocolateIceCream : IceCream () {
override fun getDescription () = "Helado de chocolate"
}
Aquí tenemos el decorador ToppingDecorator que hereda de IceCream.
abstracta clase ToppingDecorator (): IceCream () {
abstracta diversión addTopping (): String
} clase HoneyToppingDecorator ( privada val helado: IceCream): ToppingDecorator () {
anulación diversión getDescription () = iceCream.getDescription () + addTopping ()
anulación diversión addTopping () = "Con cobertura de miel &"
} clase NutsToppingDecorator ( private val iceCream: IceCream): ToppingDecorator () {
anular diversión getDescription
() = iceCream.getDescription () + addTopping ()
anula la diversión addTopping () = "Con cobertura de nueces &"
}
Código Completo:
clase abstracta IceCream {
abstract fun getDescription (): String
} clase VanillaIceCream : IceCream () {
anular diversión getDescription () = "Helado de vainilla"
} clase StrawberryIceCream : IceCream () {
anular diversión getDescription () = "Helado de fresa"
} class ChocolateIceCream : IceCream () {
override fun getDescription () = "Helado de chocolate"
} clase abstracta
ToppingDecorator (): IceCream () {
abstracta diversión addTopping (): String
} clase HoneyToppingDecorator ( privada val helado: IceCream): ToppingDecorator () {
anulación diversión getDescription () = iceCream.getDescription () + addTopping ()
anulación diversión addTopping () = "Con cobertura de miel &"
} clase NutsToppingDecorator ( private val iceCream: IceCream): ToppingDecorator () {
anular diversión getDescription
() = IceCream.getDescription () + addTopping ()
anulación diversión addTopping () = "con el desmoche de frutos secos y"
} diversión principal () {
val vanillaIceCreamWithHoneyTopping = HoneyToppingDecorator (VanillaIceCream ())
val vanillaIceCreamWithHoneyToppingDescription = vanillaIceCreamWithHoneyTopping.getDescription ()
println ( " Usted ordenó: $ {vanillaIceCreamWithHoneyToppingDescription.trimEnd ('&')} " ) val strawberryCreamWithNutsTopping = NutsToppingDecorator (StrawberryIceCream ())
val strawberryCreamWithNutsToppingDescription = strawberryCreamWithNutsTopping.getDescription ()
System.out.println ( "Usted ordenó: strawberryCreamWithNutsToppingDescription.trimEnd {$ ( '&')}" ) val chocolateIceCreamWithHoneyAndNutsTopping = NutsToppingDecorator (HoneyToppingDecorator (ChocolateIceCream ()))
val chocolateIceCreamWithHoneyAndNutsToppingDescription chocolateIceCreamWithHoneyAndNutsTopping.getDescription = ()
System.out.println ( " Usted ordenó: $ {chocolateIceCreamWithHoneyAndNutsToppingDescription.trimEnd ('&')} " )
}
The output will be:
You ordered: Vanilla ice cream With honey topping
You ordered: Strawberry ice cream With nuts topping
You ordered: Chocolate ice cream With honey topping & With nuts topping
Como puede ver, puede mezclar decoradores como desee para lograr los resultados deseados. En el primer pedido, cuando el cliente solicita helado de vainilla con cobertura de miel, la función getDescription() en la clase HoneyToppingDecorator reenvía la solicitud al objeto IceCream primero y luego agrega la responsabilidad adicional, que en nuestro caso es la cobertura.
Entonces, como recapitulación, el patrón Decorator nos permite adjuntar responsabilidades adicionales (Topping) a un objeto (objeto IceCream) de forma dinámica sin la necesidad de subclasificar IceCream para extender su funcionalidad.