Patrones de diseño_Patrones creativos-《Patrones de construcción》

Patrones de diseño_Patrones creativos-《Patrones de construcción》

Las notas están organizadas a partir de la explicación detallada de los patrones de diseño de Java por programadores de caballos oscuros, 23 patrones de diseño de Java (diagrama + análisis de código fuente del marco + combate real)

descripción general

Separar la construcción y representación de un objeto complejo para que un mismo proceso de construcción pueda crear diferentes representaciones.

  • Se separa la construcción de piezas (responsable del Constructor) y montaje (responsable del Director). Así se pueden construir objetos complejos. Este patrón es adecuado para situaciones en las que el proceso de construcción de un objeto es complejo.
  • Por la desvinculación de la construcción y el montaje. Diferentes constructores y el mismo ensamblaje pueden hacer diferentes objetos; el mismo constructor y diferentes secuencias de ensamblaje también pueden hacer diferentes objetos. Es decir, se realiza el desacoplamiento del algoritmo de construcción y el algoritmo de ensamblaje, y se realiza una mejor reutilización.
  • El patrón constructor puede separar partes de su proceso de ensamblaje y crear un objeto complejo paso a paso. El usuario solo necesita especificar el tipo de objeto complejo para obtener el objeto sin conocer los detalles de su construcción interna.

estructura

El patrón Builder incluye los siguientes roles:

  • Clase de constructor abstracto (Builder): esta interfaz estipula la creación de esas partes del objeto complejo y no implica la creación de objetos componentes específicos.

  • Concrete Builder Class (ConcreteBuilder): implementa la interfaz Builder para completar los métodos de creación específicos de cada componente de un producto complejo. Una vez finalizado el proceso de construcción, se proporciona una instancia del producto.

  • Clase de producto (Producto): El objeto complejo a crear.

  • Clase de director (Director): llama al constructor específico para crear cada parte del objeto complejo. El director no involucra la información del producto específico, y solo es responsable de garantizar que las partes del objeto se creen completamente o en un cierto orden.

El diagrama de clases es el siguiente:

ejemplo

Crear una bicicleta compartida

Producir una bicicleta es un proceso complejo que incluye la producción de componentes como el cuadro y el sillín. El marco está hecho de fibra de carbono, aleación de aluminio y otros materiales, y el asiento está hecho de caucho, cuero y otros materiales. Para la producción de bicicletas, se puede utilizar el patrón de construcción.

Aquí Bike es un producto, incluidos componentes como el cuadro y el asiento; Builder es un constructor abstracto, MobikeBuilder y OfoBuilder son constructores concretos; Director es un comandante. El diagrama de clases es el siguiente:

El código específico es el siguiente:

  • Categoría de producto (bicicleta)

    public class Bike {
          
          
        private String frame;
        private String seat;
    
        public String getFrame() {
          
          
            return frame;
        }
    
        public void setFrame(String frame) {
          
          
            this.frame = frame;
        }
    
        public String getSeat() {
          
          
            return seat;
        }
    
        public void setSeat(String seat) {
          
          
            this.seat = seat;
        }
    }
    
  • clase de constructor abstracto

    public abstract class Builder {
          
          
    
        // 声明Bike类型的变量,并进行赋值(提高复用性)
        protected Bike mBike = new Bike();
    
        public abstract void buildFrame();
        public abstract void buildSeat();
        public abstract Bike createBike();
    }
    
  • Clase de constructor de hormigón (clase Mobike Builder)

    public class MobikeBuilder extends Builder {
          
          
    
        @Override
        public void buildFrame() {
          
          
            mBike.setFrame("铝合金车架");
        }
    
        @Override
        public void buildSeat() {
          
          
            mBike.setSeat("真皮车座");
        }
    
        @Override
        public Bike createBike() {
          
          
            return mBike;
        }
    }
    
  • Clase de constructor de hormigón (ofo clase de constructor de bicicletas)

    public class OfoBuilder extends Builder {
          
          
    
        @Override
        public void buildFrame() {
          
          
            mBike.setFrame("碳纤维车架");
        }
    
        @Override
        public void buildSeat() {
          
          
            mBike.setSeat("橡胶车座");
        }
    
        @Override
        public Bike createBike() {
          
          
            return mBike;
        }
    }
    
  • clase comandante

    public class Director {
          
          
        
        // 声明builder类型的变量
        private Builder mBuilder;
    
        public Director(Builder builder) {
          
          
            mBuilder = builder;
        }
    
        // 组装自行车的功能
        public Bike construct() {
          
          
            mBuilder.buildFrame();
            mBuilder.buildSeat();
            return mBuilder.createBike();
        }
    }
    
  • clase de prueba

    public class Client {
          
          
        public static void main(String[] args) {
          
          
            showBike(new OfoBuilder());
            showBike(new MobikeBuilder());
        }
        
        private static void showBike(Builder builder) {
          
          
            // 创建指挥者对象
            Director director = new Director(builder);
            // 让指挥者指挥组装自行车
            Bike bike = director.construct();
            System.out.println(bike.getFrame());
            System.out.println(bike.getSeat());
        }
    }
    

    producción

    铝合金车架
    真皮车座
    碳纤维车架
    橡胶车座
    

Aviso:

  • El ejemplo anterior es un uso regular del modo Constructor. La clase de director Director juega un papel muy importante en el modo constructor. Se utiliza para guiar al constructor específico sobre cómo construir el producto, controlar el orden de las llamadas y devolver el clase de producto a la persona que llama Pero en algunos casos es necesario simplificar la estructura del sistema, puede poner 指挥者类和抽象建造者进行结合.

    // 抽象builder类
    public abstract class Builder {
          
          
    
        protected Bike mBike = new Bike();
    
        public abstract void buildFrame();
        public abstract void buildSeat();
        public abstract Bike createBike();
        
        public Bike construct() {
          
          
            this.buildFrame();
            this.BuildSeat();
            return this.createBike();
        }
    }
    

ilustrar:

  • Esto realmente simplifica la estructura del sistema, pero también aumenta las responsabilidades de la clase constructora abstracta y no se ajusta al principio de responsabilidad única.Si construct() es demasiado complicado, se recomienda encapsularlo en el Director.

Ventajas y desventajas

ventaja

  • La encapsulación del patrón constructor es muy buena. El uso del modo constructor puede encapsular cambios de manera efectiva. En el escenario de uso del modo constructor, la clase de producto general y la clase de constructor son relativamente estables. Por lo tanto, encapsular la lógica comercial principal en la clase comandante puede lograr una estabilidad general relativamente buena.
  • En el modo constructor, el cliente no necesita conocer los detalles de la composición interna del producto, y el producto en sí está desacoplado del proceso de creación del producto, de modo que el mismo proceso de creación puede crear diferentes objetos de producto.
  • El proceso de creación del producto se puede controlar más finamente. Descomponer los pasos de creación de productos complejos en diferentes métodos hace que el proceso de creación sea más claro y más conveniente para usar programas para controlar el proceso de creación.
  • El patrón constructor es fácil de extender. Si hay un nuevo requisito, se puede completar implementando una nueva clase de constructor, básicamente sin modificar el código que se ha probado antes, por lo que no introducirá riesgos en la función original. Cumplir con el principio de apertura y cierre.

defecto

  • Los productos creados por el modo constructor generalmente tienen más en común y sus componentes son similares.Si los productos son muy diferentes, no es adecuado utilizar el modo constructor, por lo que su alcance de uso es limitado.

Escenas a utilizar

El patrón Builder crea objetos complejos y las diversas partes de sus productos a menudo enfrentan cambios drásticos, pero el algoritmo que los combina es relativamente estable, por lo que generalmente se usa en las siguientes situaciones:

  • El objeto creado es complejo y consta de múltiples partes, cada parte enfrenta cambios complejos, pero la secuencia de construcción entre los componentes es estable.
  • El algoritmo para crear un objeto complejo es independiente de las partes constitutivas de ese objeto y de cómo se ensamblan, es decir, el proceso de construcción y la representación final del producto son independientes.

extensión de esquema

Además de los usos anteriores, el modo constructor también tiene un uso común en el desarrollo, es decir, cuando un constructor de clase necesita pasar muchos parámetros, si se crea una instancia de esta clase, la legibilidad del código será muy pobre y será difícil Es fácil introducir errores y, en este momento, el patrón del constructor se puede usar para la refactorización.

  • El código antes de la refactorización es el siguiente:

    // 手机类
    public class Phone {
          
          
        private String cpu;
        private String screen;
        private String memory;
        private String mainboard;
    
        public Phone(String cpu, String screen, String memory, String mainboard) {
          
          
            this.cpu = cpu;
            this.screen = screen;
            this.memory = memory;
            this.mainboard = mainboard;
        }
    
        public String getCpu() {
          
          
            return cpu;
        }
    
        public void setCpu(String cpu) {
          
          
            this.cpu = cpu;
        }
    
        public String getScreen() {
          
          
            return screen;
        }
    
        public void setScreen(String screen) {
          
          
            this.screen = screen;
        }
    
        public String getMemory() {
          
          
            return memory;
        }
    
        public void setMemory(String memory) {
          
          
            this.memory = memory;
        }
    
        public String getMainboard() {
          
          
            return mainboard;
        }
    
        public void setMainboard(String mainboard) {
          
          
            this.mainboard = mainboard;
        }
    
        @Override
        public String toString() {
          
          
            return "Phone{" +
                    "cpu='" + cpu + '\'' +
                    ", screen='" + screen + '\'' +
                    ", memory='" + memory + '\'' +
                    ", mainboard='" + mainboard + '\'' +
                    '}';
        }
    }
    
    public class Client {
          
          
        public static void main(String[] args) {
          
          
            // 构建Phone对象
            Phone phone = new Phone("intel", "三星屏幕" ,"金士顿", "华硕");
            System.out.println(phone);
        }
    }
    

    Lo anterior construye el objeto Teléfono en el código del cliente y pasa cuatro parámetros. ¿Qué pasa si hay más parámetros? La legibilidad del código y el costo de uso son relativamente altos.

  • Código después de la refactorización:

    // 手机类
    public class Phone {
          
          
    
        private String cpu;
        private String screen;
        private String memory;
        private String mainboard;
    
        // 私有构造方法,传递一个建造者
        private Phone(Builder builder) {
          
          
            cpu = builder.cpu;
            screen = builder.screen;
            memory = builder.memory;
            mainboard = builder.mainboard;
        }
    
        // 内部类-建造者类
        public static final class Builder {
          
          
            private String cpu;
            private String screen;
            private String memory;
            private String mainboard;
    
            public Builder() {
          
          }
    
            public Builder cpu(String val) {
          
          
                cpu = val;
                return this;
            }
            public Builder screen(String val) {
          
          
                screen = val;
                return this;
            }
            public Builder memory(String val) {
          
          
                memory = val;
                return this;
            }
            public Builder mainboard(String val) {
          
          
                mainboard = val;
                return this;
            }
            // 使用构建者创建Phone对象
            public Phone build() {
          
          
                return new Phone(this);
            }
        }
        
        @Override
        public String toString() {
          
          
            return "Phone{" +
                    "cpu='" + cpu + '\'' +
                    ", screen='" + screen + '\'' +
                    ", memory='" + memory + '\'' +
                    ", mainboard='" + mainboard + '\'' +
                    '}';
        }
    }
    
    // 测试类
    public class Client {
          
          
        public static void main(String[] args) {
          
          
            // 创建手机对象 通过构建者对象获取手机对象
            Phone phone = new Phone.Builder()
                    .cpu("intel")
                    .mainboard("华硕")
                    .memory("金士顿")
                    .screen("三星")
                    .build();
            System.out.println(phone);
        }
    }
    

    El código refactorizado es más cómodo de usar, mejora la legibilidad del código y también puede mejorar la eficiencia del desarrollo hasta cierto punto.

    El orden de construcción del modo constructor original está determinado por la clase de conductor, pero ahora el orden de construcción se entrega al cliente.

    Desde la perspectiva del diseño de software, los requisitos para los programadores son relativamente altos.

Resumir

referencia

Comparación del modo creador

Patrón de método de fábrica vs patrón de constructor

  • El patrón del método de fábrica se enfoca en la creación del objeto general, mientras que el patrón del constructor se enfoca en el proceso de construcción de componentes, con la intención de crear un objeto complejo a través de una construcción precisa paso a paso.
  • Demos un ejemplo simple para ilustrar la diferencia entre los dos. Si desea hacer un superhombre, si usa el modelo de método de fábrica, producirá directamente un superhombre con fuerza infinita, capacidad para volar y usar ropa interior; si usa el modelo de constructor, debe ensamblar las manos, la cabeza, los pies, el torso y otras partes, y luego usar la ropa interior afuera, para que nazca un superhombre.

Patrón de fábrica abstracto VS Patrón de constructor

  • El patrón de fábrica abstracto realiza la creación de familias de productos. Una familia de productos es una serie de productos de este tipo: una combinación de productos con diferentes dimensiones de clasificación. El patrón de fábrica abstracto no necesita preocuparse por el proceso de construcción, sino que solo se preocupa por qué productos son producido por qué fábricas.
  • El modo constructor requiere la construcción de productos de acuerdo con un plano específico, y su objetivo principal es producir un nuevo producto mediante el ensamblaje de piezas de repuesto.
  • Si el patrón de fábrica abstracto se considera como una fábrica de producción de autopartes, que produce una familia de productos, entonces el patrón de constructor es una fábrica de ensamblaje de automóviles, que puede devolver un automóvil completo a través del ensamblaje de partes.

Supongo que te gusta

Origin blog.csdn.net/weixin_53407527/article/details/128627841
Recomendado
Clasificación