理解设计模式—建造者模式

一、简介

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

建造者模式定义了一个新的类来构建另一个类的实例,以简化复杂对象的创建

二、模式结构

  • 抽象建造者(builder): 接口或者抽象类,定义对象组件建造方法和返回具体对象
  • 实际建造者(concreteBuilder): 实现builder
  • 管理者(director):负责安排复杂对象的建造次序
  • 产品角色(product):建造的产品

三、代码示例

组装一台电脑,使用建造者模式

product
public class Computer {
    private String cpu;
    private String Memory;
    //显卡
    private String graphics;

    public String getCpu() {
        return cpu;
    }

    public void setCpu(String cpu) {
        this.cpu = cpu;
    }

    public String getMemory() {
        return Memory;
    }

    public void setMemory(String memory) {
        Memory = memory;
    }

    public String getGraphics() {
        return graphics;
    }

    public void setGraphics(String graphics) {
        this.graphics = graphics;
    }

    @Override
    public String toString() {
        return "Computer{" +
                "cpu='" + cpu + '\'' +
                ", Memory='" + Memory + '\'' +
                ", graphics='" + graphics + '\'' +
                '}';
    }
}
builder and concreteBuilder
public interface ComputerBuilder {
    void buildCpu();
    void buildMemory();
    void buildGraphics();

    Computer buildComputer();
}
//具体建造者,使用Cpu,内存,显卡的型号在这里指定
public class ComputerBuilderImpl implements ComputerBuilder {

    private Computer c = new Computer();

    @Override
    public void buildCpu() {
        c.setCpu("I7");
    }

    @Override
    public void buildMemory() {
        c.setMemory("16G");
    }

    @Override
    public void buildGraphics() {
        c.setGraphics("GTX 2080");
    }

    @Override
    public Computer buildComputer() {
        return c;
    }
}
Director
public class Director {
	//具体组装过程,可以改变组装顺序
    public void build(ComputerBuilder computerBuilder) {
        computerBuilder.buildCpu();
        computerBuilder.buildMemory();
        computerBuilder.buildGraphics();
    }
}
测试类
public class Test {
    public static void main(String[] args) {
        //不使用建造者
        Computer c = new Computer();
        c.setCpu("I5");
        c.setMemory("8G");
        c.setGraphics("1080 TI");
        System.out.println(c);

        //使用建造者,但是不要设计师,这里可以自由选择组装电脑顺序
        ComputerBuilder computerBuilder = new ComputerBuilderImpl();
        computerBuilder.buildMemory();
        computerBuilder.buildCpu();
        computerBuilder.buildGraphics();
        Computer c1 = computerBuilder.buildComputer();
        System.out.println(c1);

        //使用建造者模式,完全托管
        ComputerBuilder cb = new ComputerBuilderImpl();
        Director director = new Director();
        director.build(cb);
        Computer c2 = cb.buildComputer();
        System.out.println(c2);

    }
}

执行结果:
Computer{cpu='I5', Memory='8G', graphics='1080 TI'}
Computer{cpu='I7', Memory='16G', graphics='GTX 2080'}
Computer{cpu='I7', Memory='16G', graphics='GTX 2080'}

四、简单建造者

public class Computer {
    private String cpu;
    private String memory;
    private String graphics;

    public String getCpu() {
        return cpu;
    }

    public void setCpu(String cpu) {
        this.cpu = cpu;
    }

    public String getMemory() {
        return memory;
    }

    public void setMemory(String memory) {
        this.memory = memory;
    }

    public String getGraphics() {
        return graphics;
    }

    public void setGraphics(String graphics) {
        this.graphics = graphics;
    }

    public static ComputerBuilder createComputerBuilder() {
        return new ComputerBuilder();
    }

    @Override
    public String toString() {
        return "Computer{" +
                "cpu='" + cpu + '\'' +
                ", memory='" + memory + '\'' +
                ", graphics='" + graphics + '\'' +
                '}';
    }

    static class ComputerBuilder {
        private Computer c = new Computer();
        public ComputerBuilder setCpu(String cpu) {
            c.setCpu(cpu);
            return this;
        }

        public ComputerBuilder setMemory(String memory) {
            c.setMemory(memory);
            return this;
        }

        public ComputerBuilder setGraphics(String graphics) {
            c.setGraphics(graphics);
            return this;
        }

        public Computer buildComputer() {
           return c;
        }
    }
}

测试类
public class Test {
    public static void main(String[] args) {
        Computer computer = Computer.createComputerBuilder().setCpu("I9").
                setMemory("32G").setGraphics("GTX 2080").buildComputer();

        System.out.println(computer);
    }
}

这种使用内部静态类的写法,省略了指挥者和抽象建造者,这是简单建造者模式的实现,可以让我们使用链式写法创建对象,看起来会简单方便很多,但是需要写过多额外代码,尤其在类属性过多的情况下。

解决上述问题的方法就是使用Lombok插件,项目中引入Lombok插件后,直接在类上加上@Builder注解,就可以直接使用链式创建对象,这种链式写法在Scala中大量使用,用起来确实很爽。

五、使用场景

  • 需要生成的产品对象有复杂的内部结构,这些产品对象通常包含多个成员属性。
  • 需要生成的产品对象的属性相互依赖,需要指定其生成顺序。
  • 对象的创建过程独立于创建该对象的类。在建造者模式中引入了指挥者类,将创建过程封装在指挥者类中,而不在建造者类中。
  • 隔离复杂对象的创建和使用,并使得相同的创建过程可以创建不同的产品

六、优缺点

优点:

  • 在建造者模式中, 客户端不必知道产品内部组成的细节,将产品本身与产品的创建过程解耦,使得相同的创建过程可以创建不同的产品对象。
  • 一个具体建造者都相对独立,而与其他的具体建造者无关,因此可以很方便地替换具体建造者或增加新的具体建造者, 用户使用不同的具体建造者即可得到不同的产品对象
  • 可以更加精细地控制产品的创建过程 。将复杂产品的创建步骤分解在不同的方法中,使得创建过程更加清晰,也更方便使用程序来控制创建过程
  • 增加新的具体建造者无须修改原有类库的代码,指挥者类针对抽象建造者类编程,系统扩展方便,符合“开闭原则

缺点:

  • 建造者模式所创建的产品一般具有较多的共同点,其组成部分相似,如果产品之间的差异性很大,则不适合使用建造者模式,因此其使用范围受到一定的限制
  • 如果产品的内部变化复杂,可能会导致需要定义很多具体建造者类来实现这种变化,导致系统变得很庞大。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值