Modo Generador (Constructor) - Principio a Aplicación Práctica (Edición Dart)

Patrones de diseño orientado a objetos
Modo Generador (Constructor) - Principio a Aplicación Práctica (Edición Dart)

- Información del artículo -
Autor: 李俊才(jcLee95)
Visítame en: https://jclee95.blog.csdn.net
Correo electrónico: [email protected] .
Shenzhen China
Dirección de este artículo: https://blog.csdn.net/qq_28550263/article/details/131729619

[Introducción]: este artículo presenta el principio y la aplicación del patrón generador.

Sección anterior: " Patrón de fábrica abstracto: del principio a la aplicación práctica (basado en el lenguaje Dart) " | Sección siguiente: " Patrón de prototipo: del principio a la aplicación práctica (basado en el lenguaje Dart) "


1. Referencias

En las dos publicaciones de blog anteriores, usamos dos ejemplos relacionados con juegos para construir un personaje de juego y un personaje de juego con equipo. Ahora todavía usamos un ejemplo para explicar el patrón del generador. Supongamos que estamos desarrollando un sistema de pedidos de restaurante y necesitamos crear objetos de plato . Un objeto plato tiene varias propiedades opcionales , como nombre, descripción, precio, calorías, etc. Cuando necesitamos crear múltiples platos diferentes, ¿cómo lo logramos?

Después de pensar, primero pensamos en dos métodos. Un método es escribir una gran clase base de platos para múltiples platos y luego producir múltiples subcategorías de platos basadas en esta clase base. De esta manera, debe enfrentar una gran cantidad de subcategorías de platos. Los parámetros más opcionales El cuanto más tiempo, más compleja la estructura. Otro método es poner todos los parámetros de diferentes tipos en el constructor de la clase de plato, o implementar un solo constructor enorme, o usar la sobrecarga del constructor para manejar diferentes parámetros, y finalmente construir diferentes platos. Obviamente, el segundo método puede conducir a un constructor relativamente complejo, especialmente cuando se aumentan los parámetros y hay platos con nuevos parámetros opcionales, lo que conducirá a una gran cantidad de cambios en el código.

Cuando los platos se vuelven cada vez más complicados, ¿hay alguna forma de evitar esta complicada situación? En este momento, podemos dividir el proceso de construcción del plato en un conjunto de pasos de construcción y construir el objeto del plato a través de un nuevo objeto que contenga esta serie de pasos de creación. Dado que diferentes objetos de plato usan diferentes parámetros opcionales, de hecho, solo usamos pasos limitados cuando creamos un plato determinado.

A través de este ejemplo, discutimos un método para construir objetos complejos, descomponer un proceso de construcción complejo en varios pasos mediante la división y generar un objeto específico mediante la combinación de diferentes pasos. Este objeto, que consta de una serie de pasos y se utiliza especialmente para generar un objeto, se denomina generador, y el modo de programación correspondiente para crear objetos de esta forma se denomina modo generador. En la siguiente sección, analizaremos en detalle los diversos componentes del modelo y sus principios funcionales.

2. ¿Qué es el patrón generador?

2.1 Principio del Patrón Constructor

El patrón constructor , también conocido como patrón constructor (Builder Pattern), nos permite usar múltiples objetos simples para construir gradualmente un objeto complejo. Este patrón permite la flexibilidad de crear diferentes tipos de objetos al separar el proceso de construcción de un objeto de su representación . Su diagrama de estructura se muestra en la Figura 1:

builder
Builder
+buildPartA()
+buildPartB()
+getResult()
ConcreteBuilder
+buildPartA()
+buildPartB()
+getResult()
Director
-builder: Builder
+construct()
+setBuilder(builder: Builder)
Product
-partA
-partB
+setPartA(partA)
+setPartB(partB)
Figura 1 Diagrama de estructura del patrón Builder

La figura incluye cuatro roles que implementan el patrón constructor, en los que el constructor (Builder) y el constructor específico (ConcreteBuilder) son responsables de construir varias partes del producto, el producto (Product) representa el objeto complejo que se está construyendo y el director (Director) coordina el trabajo del autor de la construcción y controla el proceso de construcción. Trabajan juntos para lograr la separación de la construcción y presentación de objetos, y el objetivo de crear objetos complejos de manera flexible. La descripción detallada de las funciones de cada rol en esta modalidad se muestra en la Tabla 1:

Role describir
Constructor Define una interfaz abstracta para crear partes de un objeto, incluidos métodos para construir las diferentes partes y métodos para obtener el producto final.
Constructor de hormigón (ConcreteBuilder) Implementa la interfaz del constructor y es responsable de construir las partes del producto y devolver el objeto del producto final.
Producto Representa un objeto complejo que se está construyendo, generalmente con múltiples partes. Los constructores de hormigón son los responsables de construir estas piezas y definir cómo se ensamblará el producto.
Director Responsable de usar el objeto constructor para seguir ciertos pasos para crear objetos complejos. El mentor puede ocultar el proceso de creación específico del producto y simplificar el código del cliente.
Tabla 1 Descripción de roles en el patrón generador

2.2 Escenarios de uso del modo generador

Para analizar los escenarios de uso del patrón generador, debemos comprender las ventajas relativas que podemos obtener al usar este patrón. En resumen, las ventajas del modo generador incluyen principalmente:

  1. Separa el proceso de construcción de objetos complejos de su representación, haciendo que el proceso de construcción sea más flexible y fácil de expandir y modificar.
  2. El proceso de construcción del objeto se puede controlar, de modo que el proceso de construcción se puede reutilizar y el objeto se puede construir paso a paso, lo cual es conveniente para construir objetos complejos.
  3. La estructura interna del producto está oculta, lo que hace que el proceso de creación del producto sea transparente para el cliente.

El patrón del generador es adecuado para los siguientes escenarios:

  1. Cuando el objeto que debe crearse contiene partes y pasos de creación complejos, el patrón de construcción se puede utilizar para simplificar el proceso de construcción del objeto.
  2. Cuando el proceso de construcción de un objeto debe ser diferente según diferentes parámetros u opciones de configuración, el patrón de construcción se puede utilizar para construir de manera flexible diferentes tipos de objetos.
  3. El patrón Builder es una opción útil cuando desea crear un objeto en una secuencia de pasos y desea desvincular la creación del objeto de su representación.
  4. El patrón Builder se puede usar cuando se requiere un control detallado sobre el producto durante el proceso de construcción, o cuando se deben realizar acciones o comprobaciones específicas durante el proceso de construcción.

3. Escribir código de patrón de generador en lenguaje Dart

Ahora, volviendo al ejemplo al principio de este artículo, el objetivo final que necesitamos construir es platos diferentes (Plato), que es equivalente al producto (Producto) en el modo generador. El producto es creado por el director (Director) utilizando el constructor concreto (ConcreteBuilder) de acuerdo con ciertos pasos para crear objetos complejos. El método abstracto en el constructor (abstracto) (Builder) en realidad divide el proceso de construcción en pasos específicos. Por ejemplo, buildName()el método se usa para construir el nombre del plato, buildDescriptionel método se usa para construir la descripción del plato, buildPriceel método se usa para construir el precio del plato, etc. En general, el diagrama de estructura de este ejemplo es el siguiente:

builder
Builder
+buildName(name: String)
+buildDescription(description: String)
+buildPrice(price: double)
+buildCalories(calories: int)
+getResult()
ConcreteBuilder
-dish: Dish
+buildName(name: String)
+buildDescription(description: String)
+buildPrice(price: double)
+buildCalories(calories: int)
+getResult()
Director
-builder: Builder
+setBuilder(builder: Builder)
+construct(name: String, description: String, price: double, calories: int)
Dish
-name: String
-description: String
-price: double
-calories: int
+display()
// Dish: 菜品类
class Dish {
    
    
  String name; // 名称
  String description; // 描述
  double price; // 价格
  int calories; // 热量

  Dish(this.name, this.description, this.price, this.calories);

  void display() {
    
    
    print(
        'Dish: $name, Description: $description, Price: $price, Calories: $calories');
  }
}

// Builder: 抽象建造者
abstract class Builder {
    
    
  void buildName(String name); // 构建名称
  void buildDescription(String description); // 构建描述
  void buildPrice(double price); // 构建价格
  void buildCalories(int calories); // 构建热量
  Dish getResult(); // 获取最终结果
}

// ConcreteBuilder: 具体建造者
class ConcreteBuilder implements Builder {
    
    
  late Dish dish; // 菜品对象

  ConcreteBuilder() {
    
    
    reset();
  }

  void reset() {
    
    
    dish = Dish('', '', 0.0, 0);
  }

  
  void buildName(String name) {
    
    
    dish.name = name;
  }

  
  void buildDescription(String description) {
    
    
    dish.description = description;
  }

  
  void buildPrice(double price) {
    
    
    dish.price = price;
  }

  
  void buildCalories(int calories) {
    
    
    dish.calories = calories;
  }

  
  Dish getResult() {
    
    
    final createdDish = dish;
    reset();
    return createdDish;
  }
}

// Director: 指导者
class Director {
    
    
  late Builder builder; // 建造者对象

  void setBuilder(Builder builder) {
    
    
    this.builder = builder;
  }

  void construct(String name, String description, double price, int calories) {
    
    
    builder.buildName(name);
    builder.buildDescription(description);
    builder.buildPrice(price);
    builder.buildCalories(calories);
  }
}

Puede usar el siguiente código para una prueba simple:

// Client 代码
void main() {
    
    
  final director = Director();
  final builder = ConcreteBuilder();
  director.setBuilder(builder);

  // 菜品1:小炒黄牛肉
  director.construct('小炒黄牛肉', '特殊小炒菜品,黄牛肉鲜嫩可口', 68.99, 350);
  final dish1 = builder.getResult();
  dish1.display();

  // 菜品2:剁椒鱼头
  director.construct('剁椒鱼头', '鱼头搭配剁椒酱烹饪', 58.99, 400);
  final dish2 = builder.getResult();
  dish2.display();

  // 菜品3:小炒猪肚
  director.construct('小炒猪肚', '麻辣鲜香的湖南猪肚菜品', 48.99, 300);
  final dish3 = builder.getResult();
  dish3.display();

  // 菜品4:酥香大鲫鱼
  director.construct('酥香大鲫鱼', '经酥香可口的大鲫鱼', 88.99, 450);
  final dish4 = builder.getResult();
  dish4.display();

  // 菜品5:酸辣大肠
  director.construct('酸辣大肠', '酸辣可口的大肠烹饪', 38.99, 250);
  final dish5 = builder.getResult();
  dish5.display();

  // 菜品6:香辣猪蹄
  director.construct('香辣猪蹄', '香辣多汁的猪蹄', 68.99, 400);
  final dish6 = builder.getResult();
  dish6.display();
}

En el código de cliente anterior, primero creamos la instancia del mentor y la instancia del constructor específico, y setBuilderpasamos la instancia del constructor específico al mentor a través del método. De esta forma, los métodos del director constructpueden usar esa instancia concreta del constructor.
Cuando lo usamos específicamente para crear una instancia de un determinado plato, en realidad usamos constructel método del instructor. Los múltiples parámetros de este método corresponden a múltiples pasos de creación y, finalmente, devuelven un plato real. El resultado de la operación es el siguiente:

Dish: 小炒黄牛肉, Description: 特殊小炒菜品,黄牛肉鲜嫩可口, Price: 68.99, Calories: 350
Dish: 剁椒鱼头, Description: 鱼头搭配剁椒酱烹饪, Price: 58.99, Calories: 400
Dish: 小炒猪肚, Description: 麻辣鲜香的湖南猪肚菜品, Price: 48.99, Calories: 300
Dish: 酥香大鲫鱼, Description: 经酥香可口的大鲫鱼, Price: 88.99, Calories: 450
Dish: 酸辣大肠, Description: 酸辣可口的大肠烹饪, Price: 38.99, Calories: 250
Dish: 香辣猪蹄, Description: 香辣多汁的猪蹄, Price: 68.99, Calories: 400

Al usar el modo generador, cuando el proceso de construcción de nuestro plato se vuelve más y más complicado, solo necesitamos cambiar el método de construcción por pasos y luego usar el método por pasos en el nuevo constructor concreto para construir varios platos diferentes a través del objeto instructor. platos.

Supongo que te gusta

Origin blog.csdn.net/qq_28550263/article/details/131732609
Recomendado
Clasificación