设计模式之Builder模式

Builder模式

  1. 对外部隐藏内部实现细节
  2. 分离部件和组装过程
  3. 自由扩展部件和构造过程
  4. 降低解耦,分工明确

适应场景

  1. 相同的方法,不同的执行顺序,产生不同的事件结果
  2. 多个部件和零件,都可以装配到一个对象中,但产生的运行结果又不相同时
  3. 产品类非常复杂,或者产品类中的调用顺序不同产生不同的作用
  4. 当初始化一个对象特别复杂,如参数多,且很多参数具有默认值时

UML类图

说明:
  1. 抽象类Builder由ConcreteBuilder子类来实现
  2. Director类含有一个Builder的实例对象,通过construct方法指导Builder控制Product的流程
  3. ConcreteBuilder实现具体的组装工作(new Product),组装流程由Director控制

代码实例实现

计算机的组装过程较为复杂,且组装过程也不是固定的,我们暂且将计算机的组装过程简化为构建主机,设置显示器,设置操作系统三个步骤,通过Director和具体的Builder来构建计算机对象

  • 计算机抽象类,即Product角色

    public abstract class Computer {
    
    protected String mBoard;
    protected String mDisplay;
    protected String mOS;
    
        public Computer() {
        }
    
        //设置cpu
        public void setBoard(String board){
            mBoard = board;
        }
    
        //设置显示
        public void setDisplay(String display){
            mDisplay = display;
        }
    
        //设置操作系统
        public abstract void setOS();
    
        @Override
        public String toString() {
            return "Computer { " +
                    "mBoard='" + mBoard + '\'' +
                    ", mDisplay='" + mDisplay + '\'' +
                    ", mOS='" + mOS + '\'' +
                    '}';
        }
    }
    
  • 具体的Computer类,即macboook

    public class Macbook extends Computer{
    
        public Macbook() {
        }
    
        @Override
        public void setOS() {
            mOS = "Mac OS X 10.10";
        }
    
    }
    
  • 抽象Builder类,只提供抽象方法,也不提供组装方法,有Director实现组装

    public abstract class Builder {
        //设置主机
        public abstract void buildBoard(String board);
    
        //设置显示器
        public abstract void buildDisplay(String display);
    
        //设置操作系统
        public abstract void buildOS();
    
        //创建Computer
        public abstract Computer create();
    }
    
  • MAcbookBuilder,具体的builder类

    public class MacbookBuilder extends Builder {
    
      //实例化,父类容器容纳子类对象
        private Computer mComputer = new Macbook();
    
        @Override
        public void buildBoard(String board) {
            mComputer.setBoard(board);
        }
    
        @Override
        public void buildDisplay(String display) {
            mComputer.setDisplay(display);
        }
    
        @Override
        public void buildOS() {
            mComputer.setOS();
        }
    
        @Override
        public Computer create() {
            return mComputer;
        }
    }
    
  • Director类,负责构造Computer,通过传入builder对象,负责具体的组装工作

    public class Director {
        Builder mBuilder = null;
    
        public Director(Builder builder) {
            this.mBuilder = builder;
        }
    
        public void construct(String board, String display){
            mBuilder.buildBoard(board);
            mBuilder.buildDisplay(display);
            mBuilder.buildOS();
        }
    }
    
  • 测试Main

    public class Main {
    
        public static void main(String[] args) {
    
        //Director,通过传入builder对象,可实现builder的自动组装任务
        Director pcDirector = new Director(macbookBuilder);
    
        //封装构建过程,传入具体的零件信息:4核CPU,内存2GB,MAC操作系统
        pcDirector.construct("英特尔主板 酷睿I7CPU", "Retina 显示器");
    
            //构建计算机,输出相关信息
            System.out.println("Computer Info : " + macbookBuilder.create().toString());
    
        }
    }
    
  • 运行结果

    Computer Info : Computer { mBoard='英特尔主板 酷睿I7CPU', mDisplay='Retina 显示器', mOS='Mac OS X 10.10'}
    

总结

  1. 抽象出数据原型Computer,其内包含基本的数据组成
  2. 具体的数据原型MacBook,通过继承Computer而来
  3. Builder类实现具体的装配工作,其内部必须要有数据原型对象(原料)用来装配,但是具体装配的前后顺序不是自己能控制的,只是拥有装配的能力
  4. Director指挥Builder实现具体的装配工作,其内部封装了构建复杂的产品对象过程,对外部隐藏构建的细节,控制装配的流程
  5. Builde的派生类Macbookbuilder,用于构建具体的装配对象Macbook(Computer的派生类类)
  6. Director通过指挥Builder,一起将一个复杂的对象构建和表示过程分离,使同样的构建过程可以创建不同的对象

优点

  • 良好的封装性,使用建造者模式可以使客户端不必要知道产品内部组成的细节
  • 建造者独立,容易扩展

缺点

  • 会产生多余的Builder对象以及Director对象,消耗内存

深度拓展

Android源码分析之Builder模式

坚持原创技术分享,您的支持将鼓励我继续创作!