Usando un chaleco, eres increíble: un análisis del patrón del decorador

Este artículo es el tercer artículo de la serie de patrones de diseño. Hoy, estudiaré principalmente el patrón del decorador.

No sé si no tienes ese sentimiento. Cuando lees y estudias, puedes entenderlo, pero lo olvidas después de un tiempo. Así que nos hicimos algunas preguntas desde el principio, y luego volvimos a revisar esto después de un tiempo. Varias preguntas, para consolidar el conocimiento aprendido, encadenan estos puntos de conocimiento en su cerebro. Espero poder seguir pensando repetidamente, poner los puntos en líneas y finalmente formar un bloque de conocimiento, digerirlo.

Estudiar con preguntas

  1. ¿Qué es el modo decorador?
  2. ¿En qué escenarios necesitas usar el modo decorador?
  3. ¿Cómo implementar el patrón de decorador?
  4. ¿Qué casos se pueden reflejar en el marco común o el código fuente?

El concepto de patrón decorador.

Primero echemos un vistazo a la descripción del modo decorador:

El "modo decorador" atribuye dinámicamente responsabilidades a los objetos. Para ampliar la funcionalidad, los decoradores ofrecen una alternativa más flexible que la herencia.

"Nuevos principios de diseño" : las clases deben estar abiertas para su extensión y cerradas para modificaciones.

Aunque la definición anterior explica el "papel" del patrón decorador, no explica cómo "aplicarlo" realmente en nuestra implementación.

A continuación, estudiaremos su diagrama de clases y lo analizaremos cuidadosamente en combinación con el diagrama de clases:

Del diagrama de clases anterior, comprendamos el patrón del decorador

  • El decorador y el objeto decorado tienen el mismo supertipo
  • Puede envolver un objeto (el componente específico de un componente) con uno o más decoradores
  • Dado que el decorador y el objeto decorado tienen el mismo supertipo, el objeto decorado se puede utilizar en lugar del objeto original (envuelto) en cualquier ocasión.
  • "El decorador puede agregar su propio comportamiento antes o después del comportamiento del decorador encargado para lograr un propósito específico". Veremos esto claramente más adelante en cómo usarlo.
  • Los objetos se pueden decorar en cualquier momento, por lo que puede decorar objetos de forma dinámica e ilimitada con sus decoradores favoritos en tiempo de ejecución

escenas a utilizar

Ahora hay una cafetería que puede vender varios tipos diferentes de café, como moka, capuchino, macchiato, campana, etc. Y cada café específico también se puede agregar con diferentes sabores, como espuma de leche, caramelo, leche de soja, moka, etc. Se requieren diferentes sabores para tener diferentes precios finales, si esta escena está diseñada con ideas OO, ¿qué harías?

No hay duda de que esta escena es muy adecuada para el modo decorador. En primer lugar, el decorador es nuestra variedad de café, y el decorador son nuestras diferentes especias, por lo que al calcular el precio podemos encargar capa por capa para obtener el resultado final, no mucho que decir. Veamos si usamos patrón decorador para decorar nuestro café.

Mirando el ejemplo de café de Starbucks que dimos anteriormente, ¿corresponde al marco del diagrama de clases del patrón del decorador? Todos pueden pensarlo detenidamente.

Consolidar y expandir

Ahora usemos el patrón de decorador anterior para crear una escena. Probemos si se puede implementar sin cambiar el código existente y experimentemos el encanto del patrón de diseño.

"¿Pedir un latte de espuma de leche de soja doble moka?"

¿Es muy conveniente? Usemos el modo decorador para expandir la combinación y experimentar el encanto. .

Implementación

Combinemos el ejemplo anterior y echemos un vistazo a la implementación del código:

// 饮料的基础类,即component
public abstract class Beverage {
    String description = "Unknown Beverage";

    public String getDescription() {
 return description;  }  // cost必须在子类实现  public abstract double cost(); } 

La clase abstracta de condimentos, es decir, la clase decoradora:

// 调料抽象类即装饰者类,这个类必须要能替换 Beverage,所以要继承自 Beverage 类
public abstract class CondimentDecorator extends Beverage {

    public abstract String getDescription();
}

Ahora que tenemos la clase base, aquí hay una bebida específica:

// 蓝山
public class BlueMountainCoffee extends Beverage {
    public BlueMountainCoffee() {
        description = "BlueMountainCoffee";
    }
 @Override  public double cost() {  return 0;  } }  // 卡布奇诺 public class Cappuccino extends Beverage {  public Cappuccino() {  description = "Cappuccino";  }  @Override  public double cost() {  return 23;  } }  // 意式浓缩咖啡 public class Espresso extends Beverage {  public Espresso() {  description = "Espresso";  }  @Override  public double cost() {  return 25;  } } // 拿铁 public class Latte extends Beverage {  public Latte() {  description = "Latte";  }  @Override  public double cost() {  return .89;  } } 

Ahora que hay componentes concretos y componentes abstractos, podemos implementar decoradores concretos comparando el diagrama de clases del patrón del decorador:

// 摩卡是一个装饰者,所以扩展自 CondimentDecorator
public class Mocha extends CondimentDecorator {
    Beverage beverage;
    public Mocha(Beverage beverage) {
        this.beverage = beverage;
 }  @Override  public String getDescription() {  return beverage.getDescription() + ",Mocha";  }   // 首先调用委托被装饰者对象,以计算价钱,然后再加上Mocha价钱  @Override  public double cost() {  return .20 + beverage.cost();  } } // 豆浆 public class Soy extends CondimentDecorator {  Beverage beverage;  public Soy(Beverage beverage) {  this.beverage = beverage;  }  @Override  public String getDescription() {  return beverage.getDescription() + ",Soy";  }  @Override  public double cost() {  return 2.0 + beverage.cost();  } } 

El siguiente paso es mostrar el encanto del modo decorador:

// 测试类
public class StarbuzzCoffee {
    public static void main(String[] args) {
        // 一杯Espresso,不加调料
        Beverage beverage = new Espresso();
 System.out.println(beverage.getDescription() + "$" + beverage.cost());  // 一杯加摩卡和豆浆的蓝山咖啡  Beverage beverage1 = new BlueMountainCoffee();  beverage1 = new Mocha(beverage1);  beverage1 = new Soy(beverage1);  System.out.println(beverage1.getDescription() + "$" + beverage1.cost());  } } 

En la actualidad, los objetos que creamos están codificados como nuevos, lo que no es muy amigable. A medida que aprendamos el modo de fábrica en el seguimiento, estará bien, sigue aprendiendo.

Decorador en realidad

Aquí hay algunos ejemplos de patrones decoradores en jdk que se utilizan habitualmente

E / S de Java

El orden indicado es del decorador -> decorar

LineNumberInputStream -> BufferedInputStream -> FileInputStream

De un vistazo, esto es básicamente el mismo que el diagrama de clase de patrón de decorador que mencionamos anteriormente. Creo que cuando lea las clases en el paquete de E / S de Jvaa nuevamente, seguramente dará una exclamación "wow".


¡Se acabó el texto completo! luchando

No es fácil ser original. Espero que puedas hacerme un pequeño favor. Si crees que el contenido de este artículo es algo que has ganado, ayúdame a hacer clic en "Estoy mirando" o reenviarlo y compartirlo para que lo vean más amigos.

Supongo que te gusta

Origin blog.csdn.net/taurus_7c/article/details/106969515
Recomendado
Clasificación