Patrón de diseño de decorador en Java con ejemplo

El patrón de diseño Decorator nos permite agregar dinámicamente funcionalidad y comportamiento a un objeto sin afectar el comportamiento de otros objetos existentes dentro de la misma clase. Usamos la herencia para extender el comportamiento de la clase. Esto tiene lugar en tiempo de compilación y todas las instancias de esa clase obtienen el comportamiento extendido.

  • Los patrones Decorator permiten al usuario agregar nuevas funciones a un objeto existente sin alterar su estructura. Por lo tanto, no hay cambios en la clase original.
  • El patrón de diseño del decorador es un patrón estructural que proporciona un envoltorio para la clase existente.
  • El patrón de diseño Decorator usa clases abstractas o interfaces con la composición para implementar el contenedor.
  • Los patrones de diseño de decorador crean clases de decorador, que envuelven la clase original y brindan funcionalidad adicional al mantener la firma de los métodos de clase sin cambios.
  • Los patrones de diseño de decorador se utilizan con mayor frecuencia para aplicar principios de responsabilidad única, ya que dividimos la funcionalidad en clases con áreas de interés únicas.
  • El patrón de diseño del decorador es estructuralmente casi como el patrón de la string de responsabilidad.

Recuerde: Ciertos puntos clave deben tenerse en cuenta que son los siguientes: 

  1. El patrón de diseño del decorador es útil para proporcionar capacidades de modificación en tiempo de ejecución y, por lo tanto, más flexible. Es fácil de mantener y ampliar cuando la cantidad de opciones es mayor.
  2. La desventaja del patrón de diseño del decorador es que utiliza muchos tipos de objetos similares (decoradores)
  3. El patrón Decorator se usa mucho en las clases Java IO , como FileReader , BufferedReader , etc.

Procedimiento:

  1. Crea una interfaz.
  2. Crear clases concretas implementando la misma interfaz.
  3. Cree una clase de decorador abstracto que implemente la misma interfaz anterior.
  4. Cree una clase de decorador concreta que amplíe la clase de decorador abstracto anterior.
  5. Ahora use la clase de decorador concreto creada anteriormente para decorar objetos de interfaz.
  6. Por último, verifique la salida

Implementación:

Vamos a crear una interfaz Shape y clases concretas implementando la interfaz Shape. Luego crearemos una clase de decorador abstracto ShapeDecorator implementando la interfaz Shape y teniendo el objeto Shape como su variable de instancia.

  1. ‘Shape’ es el nombre de la interfaz
  2. La clase ‘Rectángulo’ y la clase ‘Círculo’ serán clases concretas que implementen la interfaz ‘Forma’.
  3. ‘ShapeDecorator’ es nuestra clase de decorador abstracto que implementa la misma interfaz ‘Shape’.
  4. RedShapeDecorator es una clase concreta que implementa ShapeDecorator.
  5. DecoratorPatternDemo, nuestra clase de demostración usará RedShapeDecorator para decorar objetos Shape.

Paso 1: Crear una interfaz llamada ‘Shape’

Ejemplo

Java

// Interface named Shape
public interface Shape {
 
    // Method inside interface
    void draw();
}

Paso 2: Crear clases concretas implementando la misma interfaz. Rectangle.java y Circle.java son los siguientes

Ejemplo 

Java

// Class 1
// Class 1 will be implementing the Shape interface
 
// Rectangle.java
public class Rectangle implements Shape {
 
    // Overriding the method
    @Override public void draw()
    {
        // /Print statement to execute when
        // draw() method of this class is called
        // later on in the main() method
        System.out.println("Shape: Rectangle");
    }
}

Java

// Circle.java
public class Circle implements Shape {
 
    @Override
    public void draw()
    {
        System.out.println("Shape: Circle");
    }
}

 
Paso 3: Cree una clase de decorador abstracto implementando la interfaz Shape.

Ejemplo 

Java

// Class 2
// Abstract class
// ShapeDecorator.java
public abstract class ShapeDecorator implements Shape {
 
    // Protected variable
    protected Shape decoratedShape;
 
    // Method 1
    // Abstract class method
    public ShapeDecorator(Shape decoratedShape)
    {
        // This keywordd refers to current object itself
        this.decoratedShape = decoratedShape;
    }
 
    // Method 2 - draw()
    // Outside abstract class
    public void draw() { decoratedShape.draw(); }
}

 
Paso 4: Cree una clase de decorador concreta que amplíe la clase ShapeDecorator.

Ejemplo 

Java

// Class 3
// Concrete class extending the abstract class
// RedShapeDecorator.java
public class RedShapeDecorator extends ShapeDecorator {
 
    public RedShapeDecorator(Shape decoratedShape)
    {
        super(decoratedShape);
    }
 
    @Override public void draw()
    {
        decoratedShape.draw();
        setRedBorder(decoratedShape);
    }
 
    private void setRedBorder(Shape decoratedShape)
    {
      // Display message whenever function is called
        System.out.println("Border Color: Red");
    }
}

 
Paso 5: Uso de RedShapeDecorator para decorar objetos Shape.

Ejemplo 

Java

// DecoratorPatternDemo.java
 
// Class
// Main class
public class DecoratorPatternDemo {
 
    // Main driver method
    public static void main(String[] args)
    {
        // Creating an object of Shape interface
        // inside the main() method
        Shape circle = new Circle();
 
        Shape redCircle
            = new RedShapeDecorator(new Circle());
 
        Shape redRectangle
            = new RedShapeDecorator(new Rectangle());
 
        // Display message
        System.out.println("Circle with normal border");
 
        // Calling the draw method over the
        // object calls as created in
        // above classes
 
        // Call 1
        circle.draw();
 
        // Display message
        System.out.println("\nCircle of red border");
 
        // Call 2
        redCircle.draw();
 
        // Display message
        System.out.println("\nRectangle of red border");
 
        // Call 3
        redRectangle.draw();
    }
}

 
Paso 6: Verificación de la salida

Producción: 

Circle with normal border
Shape: Circle

Circle of red border
Shape: Circle
Border Color: Red

Rectangle of red border
Shape: Rectangle
Border Color: Red

Explicación de salida:  

Echando un vistazo al patrón de diseño del decorador, se puede concluir que a menudo es una opción decente en los siguientes casos en los que

  • Cuando deseamos agregar, mejorar o quizás eliminar el comportamiento o estado de los objetos.
  • Cuando solo queremos modificar la funcionalidad de un solo objeto de la clase y dejar los demás sin cambios.

Publicación traducida automáticamente

Artículo escrito por kashish2008 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 *