设计模式-Builder模式

Builder模式属于创建型模式。
它是将一个复杂对象的构建过程隐藏起来,让使用者只关系自己要生成什么样的对象。即创建和表示分离。

一个例子(做汤)

我需要做两种汤:小鸡炖蘑菇汤和海带排骨汤。
做汤工序如下:

海带排骨汤:

  1. 加入海带;
  2. 加入排骨;
  3. 加入海带排骨精粉;
  4. 煮汤;

小鸡炖蘑菇:

  1. 加入小鸡儿;
  2. 加入蘑菇;
  3. 加入小鸡炖蘑菇精粉;
  4. 煮汤;

声明“汤”对象:

public class Soup {
    /**
     * 材料1
     */
    private String cailiao1;
    /**
     * 材料2
     */
    private String cailiao2;
    /**
     * 材料3
     */
    private String cailiao3;

    //getter/setter省略
    @Override
    public String toString() {
        return "Soup{" +
                "cailiao1='" + cailiao1 + '\'' +
                ", cailiao2='" + cailiao2 + '\'' +
                ", cailiao3='" + cailiao3 + '\'' +
                '}';
    }
}    

人工做汤

    //人工做汤
    System.out.println("-----人工做汤-----");
    //制作小鸡炖蘑菇汤
    System.out.println("-----制作小鸡炖蘑菇-----");
    Soup xiaojimoguSoup = new Soup();
    xiaojimoguSoup.setCailiao1("小鸡儿");
    xiaojimoguSoup.setCailiao2("蘑菇");
    xiaojimoguSoup.setCailiao3("小鸡炖蘑菇精粉");
    System.out.println("小鸡炖蘑菇:"+xiaojimoguSoup);
    //制作海带排骨汤
    System.out.println("-----制作海带排骨汤-----");
    Soup haidaipaiguSoup = new Soup();
    haidaipaiguSoup.setCailiao1("海带");
    haidaipaiguSoup.setCailiao2("排骨");
    haidaipaiguSoup.setCailiao3("海带排骨精粉");
    System.out.println("海带排骨汤:"+haidaipaiguSoup);

image

可以看到做汤的时候需要添加什么材料全靠我自己去操作,这无疑是很复杂且繁琐的。

机器做汤(使用Builder模式)

现在我购买了一个做汤的机器,可以做各种各样的汤,这取决于你给机器选择什么样的程序
image

做汤程序通用接口:

public interface SoupProgram {
    void step1();//步骤1
    void step2();//步骤2
    void step3();//步骤3
    Soup make();//做汤
}

做小鸡炖蘑菇的程序:

public class XiaojimoguSoupProgram implements SoupProgram {
    private Soup soup = new Soup();
    @Override
    public void step1() {
        soup.setCailiao1("小鸡儿");
    System.out.println("加入小鸡儿");
    }

    @Override
    public void step2() {
        soup.setCailiao2("蘑菇");
    System.out.println("加入蘑菇");
    }

    @Override
    public void step3() {
        soup.setCailiao3("小鸡炖蘑菇精粉");
    System.out.println("加入小鸡炖蘑菇精粉");
    }

    @Override
    public Soup make() {
    System.out.println("小鸡炖蘑菇汤制作好啦~");
    return soup;
    }
}

做海带排骨汤程序:

public class HaidaipaiguSoupProgram implements SoupProgram {
    private Soup soup = new Soup();
    @Override
    public void step1() {
        soup.setCailiao1("海带");
    System.out.println("加入海带");
    }

    @Override
    public void step2() {
        soup.setCailiao2("排骨");
    System.out.println("加入排骨");
    }

    @Override
    public void step3() {
        soup.setCailiao3("海带排骨精粉");
    System.out.println("加入海带排骨精粉");
    }

    @Override
    public Soup make() {
    System.out.println("海带排骨汤制作好啦~");
    return soup;
    }
}

做汤机器:

public class SoupMakeMachine {
    public static Soup builder(SoupProgram program) {
        program.step1();
        program.step2();
        program.step3();
        return program.make();
    }
}

现在我只需要选择使用哪个做汤程序就可以用机器来完成做汤了。

    //机器做汤
    System.out.println("-----机器做汤-----");
    //制作小鸡炖蘑菇汤
    System.out.println("-----制作小鸡炖蘑菇-----");
    SoupProgram program = new XiaojimoguSoupProgram();
    System.out.println("小鸡炖蘑菇:"+SoupMakeMachine.builder(program));
    //制作海带排骨汤
    System.out.println("-----制作海带排骨汤-----");
    SoupProgram program1 = new HaidaipaiguSoupProgram();
    System.out.println("海带排骨汤:"+SoupMakeMachine.builder(program1));

image

优缺点

优点

1.隐藏对象的创建过程,将对象创建过程和对象本身解耦,使用者只需要关心要创建什么样的东西。通过这个例子人工和机器做汤的比较,很明显能发现使用机器能方便很多。现实生活中也是如此(如工厂流水线)。

2.方便扩展。上面也提到了,机器做汤,做什么样的汤取决于选择什么样的程序,如果你想做玉米萝卜汤,那你只需要给机器植入做玉米萝卜汤的程序(即实现SoupProgram接口)。

3.遵循了“开闭原则”。对象应该对扩展开放对修改关闭。

缺点

通过上面的代码,很明显能感觉到,使用这个Builder设计模式以后引入了更多的类和接口,增加了复杂度。


你可以在这里获取相关代码:设计模式-Builder模式

posted @ 2019-09-04 17:23  墨、鱼的blog  阅读(652)  评论(0编辑  收藏  举报