设计模式 - 建造者模式

定义:将一个复杂对象的构建与它的表示分离,使得同样的构建方法可以创建不同的表示 - 将对象地构造过程和组成部件解耦
功能:可选择的组装式创建对象 - (定制化创建产品)允许用户根据需求定制化创建自己所需的产品。
使用场景:

  1. 零件装配(注重零件类型):有选择地将多种零件装配成产品 - 此时,接口地调用顺序不影响创建出来的产品
  2. 顺序加工(注重装配顺序):零件的装配顺序不同,产生对象的效能也不同 - 此时,接口的调用顺序会影响创建出来产品的效能

零件装配

示例:构建一个StudyMethod对象,可任意选择readBook、watchVideos、doHomework、takeNotes四种方法。

   // Test - 零件配置顺序不影响生成的产品
   StudyMethodBuilder studyMethodBuilder = new StudyMethodBuilder();
   StudyMethod studyMethod = studyMethodBuilder.setStudyMethodTitle("Java study")
                                               .addTakeNotes()
                                               .addDoHomework()
                                               .builder();
   studyMethod.show();
// 零件装配,构建者对象 - 支持调用链方式进行零件配置
public class StudyMethodBuilder {
    private StudyMethod studyMethod = new StudyMethod();

    public StudyMethodBuilder setStudyMethodTitle(String title){
        studyMethod.setMethodTitle(title);
        return this;
    }

    public StudyMethodBuilder addWatchVedeos(){
        studyMethod.setWatchVideos(true);
        return this;
    }

    public StudyMethodBuilder addDoHomework(){
        studyMethod.setDoHomework(true);
        return this;
    }

    public StudyMethodBuilder addTakeNotes(){
        studyMethod.setTakeNotes(true);
        return this;
    }

    public StudyMethod builder(){
        return studyMethod;
    }
}

// 产品对象
public class StudyMethod {
    private String methodTitle = "study method";
    private boolean readBook = true;
    private boolean watchVideos = false;
    private boolean doHomework = false;
    private boolean takeNotes = false;

    public String getMethodTitle() { return methodTitle;}

    public void setMethodTitle(String methodTitle) {this.methodTitle = methodTitle;}

    public boolean isWatchVideos() {return watchVideos;}

    public void setWatchVideos(boolean watchVideos) {this.watchVideos = watchVideos;}

    public boolean isDoHomework() {return doHomework;}

    public void setDoHomework(boolean doHomework) {this.doHomework = doHomework;}

    public boolean isTakeNotes() {return takeNotes;}

    public void setTakeNotes(boolean takeNotes) {this.takeNotes = takeNotes;}

    public void show(){}
}

顺序加工

示例:对于已构建好的StudyMethod对象,需对readBook、watchVideos、doHomework、takeNotes四种方法安排执行时间,具有先后顺序。

   StudyPlanBuilder studyPlanBuilder = new StudyPlanBuilder(studyMethod);
   studyPlanBuilder.addReadBook(3);
   studyPlanBuilder.addTakeNotes(1);
   studyPlanBuilder.addWatchVideos(2);
   studyPlanBuilder.addDoHomework(1);
   studyPlanBuilder.addTakeNotes(2);
   studyPlanBuilder.builder().show();

// 输出:
// java study : readBook - watchVideos - doHomework - takeNotes
// 3 hours - readBook
// 1 hours - takeNotes
// 2 hours - watchVideos
// 1 hours - doHomework
// 2 hours - takeNotes
public class StudyPlan {
    private List<StudyTimeSlot> timeSlots = new ArrayList<>();
    private StudyMethod studyMethod = null;

    StudyPlan(StudyMethod studyMethod) {
        this.studyMethod = studyMethod;
    }

    void addSlot(int i, String title){
        timeSlots.add(new StudyTimeSlot(i,title));
    }

    public void show() {
        studyMethod.show();
        for(StudyTimeSlot s : timeSlots){
            System.out.println(s.time + " hours - " + s.title);
        }
    }

    class StudyTimeSlot{
        int time;
        String title;

        StudyTimeSlot(int time, String title) {
            this.time = time;
            this.title = title;
        }
    }
}
public class StudyPlanBuilder {
    private StudyPlan studyPlan = null;
    private StudyMethod studyMethod = null;

    public StudyPlanBuilder(StudyMethod studyMethod){
        this.studyMethod = studyMethod;
        this.studyPlan = new StudyPlan(studyMethod);
    }

    public void addReadBook(int i){
        studyPlan.addSlot(i,"readBook");
    }

    public void addDoHomework(int i){
        if(studyMethod.isDoHomework()){
            studyPlan.addSlot(i, "doHomework");
        }
    }

    public void addWatchVideos(int i){
        if(studyMethod.isWatchVideos()) {
            studyPlan.addSlot(i, "watchVideos");
        }
    }

    public void addTakeNotes(int i){
        if(studyMethod.isTakeNotes()) {
            studyPlan.addSlot(i, "takeNotes");
        }
    }

    public StudyPlan builder(){
        return studyPlan;
    }
}

Director - 预制的产品型号

引入一个指导类,可以由指导类直接创建出常规型号的产品。

public class Director {
    public StudyPlan buildAllDaysStudyPlan(String name){
        StudyMethodBuilder studyMethodBuilder = new StudyMethodBuilder();
        StudyMethod studyMethod = studyMethodBuilder.setStudyMethodTitle(name + " study")
                .addWatchVedeos()
                .addTakeNotes()
                .addDoHomework()
                .builder();

        StudyPlanBuilder studyPlanBuilder = new StudyPlanBuilder(studyMethod);
        studyPlanBuilder.addReadBook(3);
        studyPlanBuilder.addTakeNotes(1);
        studyPlanBuilder.addWatchVideos(2);
        studyPlanBuilder.addDoHomework(1);
        studyPlanBuilder.addTakeNotes(2);
        return studyPlanBuilder.builder();
    }
}

对比

建造者模式:侧重于零件类型和加工顺序的装配过程(组件装配)
工厂模式:侧重于屏蔽创建过程,得出统一的产品对象(制式创建对象)
模板方法模式:父类已经给定了行为规划,由子类进行对行为进行具体的实现(生成组件)

posted @ 2020-11-23 19:45  祁奇  阅读(100)  评论(0编辑  收藏  举报