zoukankan      html  css  js  c++  java
  • 生成器模式

    作用

    生成器模式是一种创建型设计模式,能够分布创建复杂对象。允许使用相同的创建代码生成不同类型和形式的对象。

    结构

    生成器接口(Builder)

    声明在所有类型生成器中通用的产品构造步骤。

    具体生成器(Concrete Builders)

    提供构造过程的不同实现,具体生成器也可以构造不遵循通用接口的产品呢。

    产品(Products)

    是最终生成的对象。由不同生成器构造的产品无需属于同一类层次结构或接口。

    主管(Director)

    定义调用构造步骤的顺序,这样就可以创建和复用特定的产品配置。

    客户端

    必须将某个生成器对象和主管类关联,只需通过主管类构造函数的参数进行一次性关联即可,伺候主管类就能使用生成器对象完成所有构造任务。

    场景

    现在一个装修公司要建一套房子,但是每套房子的配置不一样,有的是独卫,有的是双卫。有的要求先做水电工步骤,有的要求先做泥木工步骤。这种场景如果我们把建房子当作一个对象,要求当作构造参数的话,参数一旦变多,代码的可读性就会下降,而且要求整改的时候会修改到业务代码违反了开闭原则。

    解决方法

    对于每一种房子都任命一个对它施工流程非常熟悉的项目经理(Dierctor),你只要给他提要求(Builder),他自己会按照规定去指定编排一套施工流程完成并交付给你。

    实现

    // 生成器接口
    public interface Builder {
    
        void buildStepA();
    
        void buildStepB();
    
        void buildStepC();
    }
    
    // 具体生成器
    public class ConcreteBuilderA implements Builder {
    
        private Villa result;
    
        @Override
        public void buildStepA() {
            System.out.println("做独卫");
        }
    
        @Override
        public void buildStepB() {
            System.out.println("泥木工程用粗砂");
        }
    
        @Override
        public void buildStepC() {
            System.out.println("水电工程开关用松下");
        }
    
        public Villa getResult() {
            return result;
        }
    }
    
    public class ConcreteBuilderB implements Builder {
    
        private Department result;
    
        @Override
        public void buildStepA() {
            System.out.println("做双卫");
        }
    
        @Override
        public void buildStepB() {
            System.out.println("泥木工程用细沙");
        }
    
        @Override
        public void buildStepC() {
            System.out.println("水电工程开关用西门子");
        }
    
        public Department getResult() {
            return result;
        }
    }
    
    // 具体产品
    public class Villa {
    
        public Villa() {
            System.out.println("这是别墅");
        }
    
    }
    
    public class Department {
    
        public Department() {
            System.out.println("这是公寓");
        }
    }
    
    // 主管
    public class Director {
    
        private Builder builder;
    
        public Director(Builder builder) {
            this.builder = builder;
        }
        // 根据不同的要求规划不同的流程
        public void make(String type) {
            if (type.equals("别墅")){
                builder.buildStepA();
                builder.buildStepC();
                builder.buildStepB();
            }else if(type.equals("公寓")){
                builder.buildStepC();
                builder.buildStepA();
            }
        }
    }
    
    // 客户端
    public class Client {
        public static void main(String[] args) {
            // 业主提供了B建筑方式
            ConcreteBuilderB builderB = new ConcreteBuilderB();
            // 将该建筑方式告知了项目经理
            Director director = new Director(builderB);
            // 造别墅,建造方式在make方法里订好了
            director.make("别墅");
    
            System.out.println("===========");
            // 造公寓
            director.make("公寓");
    				// 获得结果
            Department result = builderB.getResult();
        }
    }
    
    

    总结

    • 可以避免较多参数构造函数的方法
    • 可以分步创建对象,并可以指定创建的方式
    • 主管类接收具体的创建方法,根据不同的要求创建不同形式的产品
    • 缺点是会增加多个具体生成器或产品类
  • 相关阅读:
    php 用csv文件导出大量数据初方案
    用php导入10W条+ 级别的csv大文件数据到mysql。导出10W+级别数据到csv文件
    升级 phpStudy 中 MySQL 版本至 5.7.17
    使用 mybatis-generator 自动生成 MyBatis 代码
    使用 JSON-lib 出现异常 java.lang.reflect.InvocationTargetException
    Eclipse 中 Java 代码报版本错误的问题
    Maven 的安装与配置
    Java 中 & | ^ 运算符的简单使用
    经典词句赏析
    酒色财气诗
  • 原文地址:https://www.cnblogs.com/jimmyhe/p/15063602.html
Copyright © 2011-2022 走看看