Patrón decorador "Patrón de diseño"

1. ¿Qué es el patrón decorador?

Cuando es necesario expandir las funciones de una clase, generalmente se puede usar la herencia, sin embargo, si hay muchos tipos de funciones que necesitan expandirse, inevitablemente se generarán muchas subclases, lo que aumentará la complejidad del sistema. expandir funciones, debemos poder Anticipar estas funciones extendidas significa que estas funciones deben determinarse en el momento de la compilación. Entonces, ¿hay alguna manera mejor de ampliar la funcionalidad? La respuesta es el patrón decorador.

El patrón decorador puede agregar dinámicamente algunas responsabilidades adicionales al objeto para expandir la función. Se pueden seleccionar diferentes decoradores en tiempo de ejecución para lograr diferentes comportamientos. Es más flexible que usar la herencia. Al organizar y combinar diferentes clases de decoración, puede crear. produce muchos comportamientos diferentes y obtiene objetos con funciones más poderosas; cumple con el "principio de apertura y cierre", y la clase decorada y la clase decorada cambian de forma independiente. El usuario puede agregar nuevas clases decorativas y clases decoradas según sea necesario, y luego modificar Cuando los use Combinación, no es necesario cambiar el código original.

Sin embargo, el patrón decorador también tiene desventajas. Primero, generará muchos objetos pequeños, lo que aumenta la complejidad del sistema. Segundo, es más difícil de solucionar problemas. Para objetos decorados varias veces, encontrar errores durante la depuración puede requerir pasos -Solución de problemas paso a paso, que es más engorroso.

2. Diagrama de estructura UML

  • Componente: el componente abstracto define una interfaz de objeto y puede agregar dinámicamente responsabilidades a este objeto.
  • Componente concreto: un componente concreto define un objeto específico y también puede agregar algunas responsabilidades a este objeto.
  • Decorador: clase decorativa abstracta, heredada de Component, que extiende las funciones de la clase Component de clases externas, pero para Component, no es necesario conocer la existencia de Decorator.
  • ConcreteDecorator: Clase de decoración de hormigón, que tiene la función de agregar responsabilidades al Componente.

Tanto el decorador como el objeto decorado tienen una superclase común, pero el propósito de la herencia aquí es heredar el tipo, no el comportamiento.

3. Implementación del código

3.1 Ejemplo de código uno

//定义被装饰者
interface Human
{
    void wearClothes();
}
 
//定时装饰者
abstract class Decorator implements Human
{
    private Human human;
 
    public Decorator(Human human)
    {
        this.human = human;
    }
 
    @Override
    public void wearClothes()
    {
        human.wearClothes();
    }
}
 
//下面定义三种装饰,这是第一个,第二个第三个功能依次细化,即装饰者的功能越来越多
class Decorator_zero extends Decorator {
 
    public Decorator_zero(Human human) {
        super(human);
    }
 
    public void goHome() {
        System.out.println("进房子。。");
    }
 
    @Override
    public void wearClothes() {
        super.wearClothes();
        goHome();
    }
}
 
class Decorator_first extends Decorator {
 
    public Decorator_first(Human human) {
        super(human);
    }
 
    public void goClothespress() {
        System.out.println("去衣柜找找看。。");
    }
 
    @Override
    public void wearClothes() {
        super.wearClothes();
        goClothespress();
    }
}
 
class Decorator_two extends Decorator {
 
    public Decorator_two(Human human) {
        super(human);
    }
 
    public void findClothes() {
        System.out.println("找到一件D&G。。");
    }
 
    @Override
    public void wearClothes() {
        super.wearClothes();
        findClothes();
    }
}
 
 
class Person implements Human {
 
    @Override
    public void wearClothes() {
        System.out.println("穿什么呢。。");
    }
}
 
//测试类
public class DecoratorTest
{
    public static void main(String[] args)
    {
        Human person = new Person();
        Decorator decorator = new Decorator_two(new Decorator_first(new Decorator_zero(person)));
        decorator.wearClothes();
    }
}

resultado de la operación:

De hecho, se trata de entrar a la casa a buscar ropa y enriquecer los detalles a través de la decoración de tres capas del decorador.Los puntos clave de la demo:

(1) La clase abstracta Decorador contiene la interfaz Humana y todos los métodos se delegan a la interfaz para su invocación, con el propósito de entregarlos a la clase de implementación de la interfaz para su invocación.

(2) La subclase de la clase abstracta Decorador, es decir, el decorador concreto, tiene un método constructor que llama a super(humano), lo que refleja el principio de que la clase abstracta depende de la implementación de la subclase, es decir, la abstracción depende de la implementación. Debido a que los parámetros del constructor son todos de tipo Humano, siempre que se pase la clase de implementación Humana, se mostrará la estructura de Decorator dt = new Decorator_ second (new Decorator_first (new Decorator_zero (human))), por lo que al llamar a dt. wearClothes(), y debido a que en cada clase de decorador específica, primero se llama al método super.wearClothes(), y el constructor ha pasado el super y apunta a una clase de decorador específica, entonces la llamada final es el método de la decoración clase, y luego llama a su propio método de decoración, que muestra un comportamiento decorativo y en forma de cadena similar al filtrado.

(3) La clase decorada específica puede definir el estado inicial o la decoración inicial de sí misma, y ​​los comportamientos decorativos posteriores se embellecerán y decorarán paso a paso sobre esta base.

(4) El principio de diseño del patrón decorador es: abierto a extensión y cerrado a modificación. Esta oración se refleja en que si desea extender el comportamiento de la clase decorada, no necesita modificar la clase abstracta del decorador, solo Solo es necesario heredar la clase abstracta del decorador e implementar. Se pueden usar algunas decoraciones o comportamientos adicionales para empaquetar el objeto decorado. Por lo tanto: la extensión se refleja en la herencia y la modificación se refleja en subclases, en lugar de clases abstractas específicas, lo que encarna plenamente el principio de inversión de dependencia, que es el patrón decorador que entiendo.

3.2 Ejemplo de código 2

Ahora necesitamos una hamburguesa, el cuerpo principal es un muslo de pollo, puedes optar por agregarle lechuga, salsa, pimientos y muchos otros ingredientes, en este caso puedes usar el modo decorador.

Clase base de hamburguesa (decorada, equivalente a Humano arriba)

public abstract class Humburger {  
      
    protected  String name ;  
      
    public String getName(){  
        return name;  
    }  
    public abstract double getPrice();  
}  

Clase de muslo de pollo (el estado inicial de la persona decorada, algunas decoraciones simples propias, equivalentes a la Persona anterior) 

public class ChickenBurger extends Humburger {  
      
    public ChickenBurger(){  
        name = "鸡腿堡";  
    }  
  
    @Override  
    public double getPrice() {  
        return 10;  
    }  
}  

La clase base de ingredientes (decorador, usado para decorar hamburguesas en múltiples capas, agregando algunos ingredientes a cada capa de decoración, equivalente al Decorador anterior)

public abstract class Condiment extends Humburger {  
      
    public abstract String getName();  
}  

Lechuga (la primera capa de decoradores, equivalente a decorator_zero arriba)

public class Lettuce extends Condiment {  
      
    Humburger humburger;  
      
    public Lettuce(Humburger humburger){  
        this.humburger = humburger;  
    }  
  
    @Override  
    public String getName() {  
        return humburger.getName()+" 加生菜";  
    }  
  
    @Override  
    public double getPrice() {  
        return humburger.getPrice()+1.5;  
    }  
}  

pepper (segunda capa de decoradores, equivalente a decorator_first arriba)

public class Chilli extends Condiment {  
      
    Humburger humburger;  
      
    public Chilli(Humburger humburger){  
        this.humburger = humburger;  
          
    }  
  
    @Override  
    public String getName() {  
        return humburger.getName()+" 加辣椒";  
    }  
  
    @Override  
    public double getPrice() {  
        return humburger.getPrice();  //辣椒是免费的哦  
    }  
}  

Clase de prueba:

package decorator;  
  
public class Test {  
    public static void main(String[] args) {  
        Humburger humburger = new ChickenBurger();  
        System.out.println(humburger.getName()+"  价钱:"+humburger.getPrice());  
        Lettuce lettuce = new Lettuce(humburger);  
        System.out.println(lettuce.getName()+"  价钱:"+lettuce.getPrice());  
        Chilli chilli = new Chilli(humburger);  
        System.out.println(chilli.getName()+"  价钱:"+chilli.getPrice());  
        Chilli chilli2 = new Chilli(lettuce);  
        System.out.println(chilli2.getName()+"  价钱:"+chilli2.getPrice());  
    }  
}  

Producción:

Hamburguesa de Pierna de Pollo Precio: 10.0  
Hamburguesa de Pierna de Pollo con Lechuga Precio: 11.5  
Hamburguesa de Pierna de Pollo con Chile Precio: 10.0  
Hamburguesa de Pierna de Pollo con Lechuga y Chile Precio: 11.5  

Enlace original:  Tipo estructural de patrón de diseño Java: Patrón decorador_blog-CSDN de Zhang Weipeng 

Supongo que te gusta

Origin blog.csdn.net/m0_50370837/article/details/126254405
Recomendado
Clasificación