Patrón decorador | Conjunto 1 (fondo)

Para comprender el patrón del decorador, consideremos un escenario inspirado en el libro «Patrón de diseño de cabeza primero». Supongamos que estamos creando una aplicación para una pizzería y necesitamos modelar sus clases de pizza. Suponga que ofrecen cuatro tipos de pizzas: Peppy Paneer, Farmhouse, Margherita y Chicken Fiesta. Inicialmente solo usamos la herencia y abstraemos la funcionalidad común en una clase Pizza  .

pizza1Cada pizza tiene un costo diferente. Hemos anulado getCost() en las subclases para encontrar el costo apropiado. Ahora supongamos un nuevo requisito, además de una pizza, el cliente también puede pedir varios ingredientes como tomate fresco, paneer, jalapeño, pimiento, barbacoa, etc. Pensemos por un momento cómo acomodamos los cambios en las clases anteriores para que el cliente pueda elegir la pizza con ingredientes y obtengamos el costo total de la pizza y los ingredientes que elija el cliente. Veamos varias opciones. Opción 1 Crea una nueva subclase para cada aderezo con una pizza. El diagrama de clases se vería así:pizza2

Esto parece muy complejo. Hay demasiadas clases y es una pesadilla de mantenimiento. Además, si queremos agregar un nuevo aderezo o pizza, tenemos que agregar tantas clases. Esto es obviamente muy mal diseño.

  Opción 2: agreguemos variables de instancia a la clase base de pizza para representar si cada pizza tiene o no un aderezo. El diagrama de clases se vería así:pizza3

El getCost() de la superclase calcula los costos de todos los ingredientes, mientras que el de la subclase agrega el costo de esa pizza específica.  

// Sample getCost() in super class
public int getCost()
{
    int totalToppingsCost = 0;
    if (hasJalapeno() )
        totalToppingsCost += jalapenoCost;
    if (hasCapsicum() )
        totalToppingsCost += capsicumCost;

    // similarly for other toppings
    return totalToppingsCost;
}
// Sample getCost() in subclass
public int getCost()
{
    // 100 for Margherita and super.getCost()
    // for toppings.
    return super.getCost() + 100;
}

Este diseño se ve bien al principio, pero echemos un vistazo a los problemas asociados con él.

  • Los cambios de precio en los ingredientes darán lugar a la alteración del código existente.
  • Los nuevos ingredientes nos obligarán a agregar nuevos métodos y modificar el método getCost() en la superclase.
  • Para algunas pizzas, algunos ingredientes pueden no ser apropiados pero la subclase los hereda.
  • ¿Qué pasa si el cliente quiere doble capsicum o queso doble?

En resumen, nuestro diseño viola uno de los principios de diseño más populares: el principio abierto-cerrado , que establece que las clases deben estar abiertas para la extensión y cerradas para la modificación. En el próximo conjunto, presentaremos el patrón Decorator y lo aplicaremos al problema anterior.

Referencias:  Head First Design Patterns (Libro).

Este artículo es una contribución de Sulabh Kumar . Si le gusta GeeksforGeeks y le gustaría contribuir, también puede escribir un artículo y enviarlo por correo a review-team@geeksforgeeks.org. Vea su artículo que aparece en la página principal de GeeksforGeeks y ayude a otros Geeks.

Escriba comentarios si encuentra algo incorrecto o si desea compartir más información sobre el tema tratado anteriormente.

Publicación traducida automáticamente

Artículo escrito por GeeksforGeeks-1 y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *