设计模式---建造者(Builder)模式

1 定义

官方定义:把复杂对象构建与其表示分离,使得同样的构建过程可以创建不同的表示。

个人理解,在创建一个对象的时,需要很多的步骤,而这些步骤基本是保持不变的,例如,画人物,躯干,四肢,头,头上的七窍,人的基本组成是固定不变的,我们把步骤抽象出来成一个建造者接口或抽象类,要生成这个对象,交给建造者去建造,建造者造好,直接获取表示出来。

2 结构与实现

建造者模式结构图如下:

建造者模式由产品,抽象建造者、具体建造者、指挥者4 个要素构成。指挥者有时也可以不要,后面代码中6.2节有讲解。

建造者模式的主要角色如下:

1.产品(Product):它是包含多个组成部件的复杂对象,由具体建造者来创建其各个零部件。

2.抽象建造者(Builder):它是一个包含创建产品各个子部件的抽象方法的接口,通常还包含一个返回复杂产品(Product)的方法 getProduct()。

3.具体建造者(Concrete Builder):实现 Builder 接口,完成复杂产品的各个部件的具体创建方法。

4.指挥者(Director):它调用建造者对象中的部件构造与装配方法完成复杂对象的创建,在指挥者中不涉及具体产品的信息。

3 优缺点

3.1 优点

1.封装性好,构建和表示分离。

2.扩展性好,各个具体的建造者相互独立,有利于系统的解耦。

3.客户端不必知道产品内部组成的细节,建造者可以对创建过程逐步细化,而不对其它模块产生任何影响,便于控制细节风险。

3.2 缺点

1.产品的组成部分必须相同,这限制了其使用范围。

2.如果产品的内部变化复杂,如果产品内部发生变化,则建造者也要同步修改,后期维护成本较大。

4 适用场景

1.相同的方法,不同的执行顺序,产生不同的结果。

2.多个部件或零件,都可以装配到一个对象中,但是产生的结果又不相同。

3.产品类非常复杂,或者产品类中不同的调用顺序产生不同的作用。

4.初始化一个对象特别复杂,参数多,而且很多参数都具有默认值。

5 建造者模式和工厂模式的区别

建造者模式唯一区别于工厂模式的是针对复杂对象的创建。也就是说,如果创建简单对象,通常都是使用工厂模式进行创建,而如果创建复杂对象,就可以考虑使用建造者模式。

具体来说,有以下几方面区别:

1.建造者模式更加注重方法的调用顺序,工厂模式注重创建对象。

2.创建对象的力度不同,建造者模式创建复杂的对象,由各种复杂的部件组成,工厂模式创建出来的对象都一样

3.关注重点不一样,工厂模式只需要把对象创建出来就可以了,而建造者模式不仅要创建出对象,还要知道对象由哪些部件组成。

4.建造者模式根据建造过程中的顺序不一样,最终对象部件组成也不一样。

6 代码示例

代码示例包含两个部分,一个部分是Director、Builder和Product形成的建造者模式,另一个部分是通过静态内部类方式实现零件无序装配话构造。

6.1 Director、Builder和Product形成的建造者模式

电脑(product)组装,有主板,CPU,内存,硬盘,机箱壳,五个步骤,建造者富士康负责为我们组装,联想是我们的指挥者,我们买电脑不找富士康,找联想就可以了。

6.1.1 电脑产品 Computer

/**
 * @program: design-pattern-learning
 * @author: zgr
 * @create: 2021-09-26 11:08
 **/
public class Computer {
    List<String> components = new ArrayList<>();

    public void show(){
        System.out.println("computer include: ");
        for (String s: components) {
            System.out.println(s);
        }
    }
}

6.1.2 组装电脑抽象接口 ComputerBuilder

/**
 * @program: design-pattern-learning
 * @author: zgr
 * @create: 2021-09-26 11:11
 **/
public interface ComputerBuilder {

    /**
     * 组装主板
     */
    void constructBoard();

    /**
     * 组装cpu
     */
    void constructCpu();

    /**
     * 组装内存条
     */
    void constructMemory();

    /**
     * 组装硬盘
     */
    void constructHardDisk();

    /**
     * 组长机箱壳
     */
    void constructCase();

    /**
     * 返回电脑成品
     * @return 电脑
     */
    Computer getComputer();
}

6.1.3 具体建造者富士康 FoxconnBuilder

/**
 * @program: design-pattern-learning
 * @author: zgr
 * @create: 2021-09-26 11:20
 **/
public class FoxconnBuilder implements ComputerBuilder{

    private Computer computer = new Computer();

    @Override
    public void constructBoard() {
        computer.components.add("lenovo board");
    }

    @Override
    public void constructCpu() {
        computer.components.add("lenovo cpu");
    }

    @Override
    public void constructMemory() {
        computer.components.add("lenovo memory");
    }

    @Override
    public void constructHardDisk() {
        computer.components.add("lenovo hard disk");
    }

    @Override
    public void constructCase() {
        computer.components.add("lenovo case");
    }

    @Override
    public Computer getComputer(){
        return computer;
    }
}

6.1.4 指挥者联想 LenovoDirector

/**
 * @program: design-pattern-learning
 * @author: zgr
 * @create: 2021-09-26 11:31
 **/
public class LenovoDirector {

    private ComputerBuilder computerBuilder;

    public LenovoDirector(ComputerBuilder computerBuilder){
        this.computerBuilder = computerBuilder;
    }


    public Computer getComputer(){
        computerBuilder.constructBoard();
        computerBuilder.constructCpu();
        computerBuilder.constructMemory();
        computerBuilder.constructHardDisk();
        computerBuilder.constructCase();

        return computerBuilder.getComputer();
    }
}

6.1.5 主函数

public class MainClass {
    public static void main(String[] args) {
        LenovoDirector lenovoDirector = new LenovoDirector(new FoxconnBuilder());
        Computer computer = lenovoDirector.getComputer();
        computer.show();
    }
}

6.1.6 运行结果

6.2 静态内部类方式实现零件无序装配话构造

手机(product)组装,有主板,CPU,存储,手机壳四个步骤,建造者广达负责为我们组装,apple直接找广达提货拿到手机,不要指挥者,广达组装手机的四个步骤可以根据需要进行调换。 

6.2.1 手机产品 Telephone

/**
 * @program: design-pattern-learning
 * @author: zgr
 * @create: 2021-09-26 11:08
 **/
public class Telephone {
    List<String> components = new ArrayList<>();

    public void show(){
        System.out.println("telephone include: ");
        for (String s: components) {
            System.out.println(s);
        }
    }
}

6.2.2 组装手机抽象接口 TelephoneBuilder

/**
 * @program: design-pattern-learning
 * @author: zgr
 * @create: 2021-09-26 12:06
 **/
public interface TelephoneBuilder {

    /**
     * 组装主板
     * @return 手机构建者
     */
    TelephoneBuilder constructBoard();

    /**
     * 组装cpu
     * @return 手机构建者
     */
    TelephoneBuilder constructCpu();

    /**
     * 组装存储
     * @return 手机构建者
     */
    TelephoneBuilder constructMemory();

    /**
     * 组长手机壳
     * @return 手机构建者
     */
    TelephoneBuilder constructCase();

    /**
     * 返回电脑成品
     * @return 电脑
     */
    Telephone getTelephone();
}

6.2.3 广达建造者 QuantaBuilder

/**
 * @program: design-pattern-learning
 * @author: zgr
 * @create: 2021-09-26 12:04
 **/
public class QuantaBuilder implements TelephoneBuilder{
    private Telephone telephone;

    public QuantaBuilder(){
        this.telephone = new Telephone();
    }

    @Override
    public TelephoneBuilder constructBoard() {
        telephone.components.add("apple board");
        return this;
    }

    @Override
    public TelephoneBuilder constructCpu() {
        telephone.components.add("apple cpu");
        return this;
    }

    @Override
    public TelephoneBuilder constructMemory() {
        telephone.components.add("apple memory");
        return this;
    }

    @Override
    public TelephoneBuilder constructCase() {
        telephone.components.add("apple case");
        return this;
    }

    @Override
    public Telephone getTelephone() {
        return telephone;
    }
}

6.2.4 主函数

/**
 * @program: design-pattern-learning
 * @author: zgr
 * @create: 2021-09-26 11:08
 **/
public class MainClass {
    public static void main(String[] args) {
        QuantaBuilder quantaBuilder = new QuantaBuilder();
        Telephone telephone = quantaBuilder.
                constructBoard()
                .constructMemory()
                .constructCpu()
                .constructCase()
                .getTelephone();
        telephone.show();
    }
}

6.2.5 运行结果

6.3 总结

两种代码实现,第一种有指挥者适用于建造步骤不变的情况,第二种静态内部类实现方式灵活,对各步骤的先后顺序没有特别要求。 

7 引用

1.《大话设计模式》

2.秒懂设计模式之建造者模式(Builder pattern)

3.建造者模式(Bulider模式)详解

4.Java 设计模式——建造者模式(Builder Pattern)

8 源代码

design-pattern-learning/src/com/hz/design/pattern/builder at main · airhonor/design-pattern-learning · GitHub

猜你喜欢

转载自blog.csdn.net/honor_zhang/article/details/120488777