常用的设计模式之建造者模式

建造者模式:是将一个复杂的对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。

一、简介

  1. 定义:将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示
  2. 主要作用:在用户不知道对象的建造过程和细节的情况下就可以直接创建复杂的对象。
  3. 如何使用:用户只需要给出指定复杂对象的类型和内容,建造者模式负责按顺序创建复杂对象(把内部的建造过程和细节隐藏起来)
  4. 解决的问题:(1)方便用户创建复杂的对象(不需要知道实现过程)(2)代码复用性 & 封装性(将对象构建过程和细节进行封装 & 复用)
  5. 注意事项:与工厂模式的区别是:建造者模式更加关注与零件装配的顺序,一般用来创建更为复杂的对象

二、适用场景

  1. 隔离复杂对象的创建和使用,相同的方法,不同执行顺序,产生不同事件结果
  2. 多个部件都可以装配到一个对象中,但产生的运行结果不相同
  3. 产品类非常复杂或者产品类因为调用顺序不同而产生不同作用
  4. 初始化一个对象时,参数过多,或者很多参数具有默认值
  5. Builder模式不适合创建差异性很大的产品类,产品内部变化复杂,会导致需要定义很多具体建造者类实现变化,增加项目中类的数量,增加系统的理解难度和运行成本
  6. 需要生成的产品对象有复杂的内部结构,这些产品对象具备共性;    

三、代码实现

  • 指挥者(Director)直接和客户(Client)进行需求沟通;
  • 沟通后指挥者将客户创建产品的需求划分为各个部件的建造请求(Builder);
  • 将各个部件的建造请求委派到具体的建造者(ConcreteBuilder);
  • 各个具体建造者负责进行产品部件的构建;
  • 最终构建成具体产品(Product)。

 (1) 产品角色:包含多个组成部件的复杂对象。

class Product {
    private String partA;
    private String partB;
    private String partC;
    public void setPartA(String partA) {
        this.partA = partA;
    }
    public void setPartB(String partB) {
        this.partB = partB;
    }
    public void setPartC(String partC) {
        this.partC = partC;
    }
    public void show() {
        //显示产品的特性
    }
}

(2) 抽象建造者:包含创建产品各个子部件的抽象方法。

abstract class Builder {
    //创建产品对象
    protected Product product = new Product();
    public abstract void buildPartA();
    public abstract void buildPartB();
    public abstract void buildPartC();
    //返回产品对象
    public Product getResult() {
        return product;
    }
}
(3) 具体建造者:实现了抽象建造者接口。
public class ConcreteBuilder extends Builder {
    public void buildPartA() {
        product.setPartA("建造 PartA");
    }
    public void buildPartB() {
        product.setPartB("建造 PartB");
    }
    public void buildPartC() {
        product.setPartC("建造 PartC");
    }
}

(4) 指挥者:调用建造者中的方法完成复杂对象的创建。

class Director {
    private Builder builder;
    public Director(Builder builder) {
        this.builder = builder;
    }
    //产品构建与组装方法
    public Product construct() {
        builder.buildPartA();
        builder.buildPartB();
        builder.buildPartC();
        return builder.getResult();
    }
}

(5) 客户类。

public class Client {
    public static void main(String[] args) {
        Builder builder = new ConcreteBuilder();
        Director director = new Director(builder);
        Product product = director.construct();
        product.show();
    }
}

四、建造者模式和工厂模式的区别

  • 建造者模式更加注重方法的调用顺序,工厂模式注重创建对象。
  • 创建对象的力度不同,建造者模式创建复杂的对象,由各种复杂的部件组成,工厂模式创建出来的对象都一样
  • 关注重点不一样,工厂模式只需要把对象创建出来就可以了,而建造者模式不仅要创建出对象,还要知道对象由哪些部件组成。
  • 建造者模式根据建造过程中的顺序不一样,最终对象部件组成也不一样。

五、其它使用

除了上面的用途外,还有另外一个常用的使用方式,就是当一个类构造器需要传入很多参数时,如果创建这个类的实例,代码可读性会非常差,而且很容易引入错误,此时就可以利用 builder模式进行重构:
// 省略 getter 和 setter 方法 
public class Computer { 
    private String cpu; 
    private String screen; 
    private String memory; 
    private String mainboard; 
    public Computer(String cpu, String screen, String memory, String mainboard) { 
        this.cpu = cpu; 
        this.screen = screen; 
        this.memory = memory; 
        this.mainboard = mainboard; 
    } 
} 
public class NewComputer { 
    private String cpu; 
    private String screen; 
    private String memory; 
    private String mainboard; 
    public NewComputer() { 
        throw new RuntimeException(“can’t init”); 
    } 
    private NewComputer(Builder builder) { 
        cpu = builder.cpu; 
        screen = builder.screen; 
        memory = builder.memory; 
        mainboard = builder.mainboard; 
    } 
    public static final class Builder { 
        private String cpu; 
        private String screen; 
        private String memory; 
        private String mainboard; 
        
    public Builder() {} 
    
    public Builder cpu(String val) { 
        cpu = val; 
        return this; 
    } 
    public Builder screen(String val) { 
        screen = val; 
        return this; 
    } 
    public Builder memory(String val) { 
        memory = val; 
        return this; 
    } 
    public Builder mainboard(String val) { 
        mainboard = val; 
        return this; 
    } 
    public NewComputer build() {
        return new  NewComputer(this);} 
    } 
} 

客户端使用:点击查看代码
public class Click { 
    public static void main(String[] args) { 
        // 非 Builder 模式 
        Computer computer = new Computer(“cpu”, “screen”, “memory”, “mainboard”); 
        // Builder 模式 
        NewComputer newComputer = new NewComputer.Builder() 
        .cpu(“cpu”) 
        .screen(“screen”) 
        .memory(“memory”) 
        .mainboard(“mainboard”) 
        .build(); 
    } 
} 


 个人理解,不喜勿喷,如有侵权,请联系我删除。
posted @ 2021-08-11 10:21  搬运工达人  阅读(74)  评论(0)    收藏  举报