建造者模式

建造者模式

前言

​ 本人本科在读大二,准确来说,从大一下开始认认真真学习Java,从面向对象基础到servlet,jsp,并且通过原生JavaWeb项目进入了自己学校的工作室,然后又学习了各大框架,直到springboot,并且利用它做了两个项目,但是我觉得越往后学,感觉自己没有学到很硬核的东西,后面我就有想学习数据结构和设计模式的想法,所以我就打算跟着视频去学一学。前面我已经学了几个设计模式,感觉设计的非常巧妙,所以想在这里记录一下。

定义

The intent of the Builder design pattern is to separate the construction of a complex object from its representation. By doing so the same construction process can create different representations.
将一个复杂对象的构建与其表示分离,使得同样的构建过程可以创建不同的表示。

其实说实话,看到这个,估计大部分人都不知道是什么意思,稍后我们会慢慢解释的。

实现1.0

在这里,我们举一个例子,我们要去购买电脑,电脑肯定有配置,供我们选择,所以首先实例化一个电脑类

class Computer {
    private String cpu;
    private String gpu;
    private String memory;
    private String hd;
}

怕占用空间,我就把get,set和toString方法删去了。

现在我们就需要买电脑了,我们肯定要关心配置,所以就自己去配。

public class AppTest {
    public static void main(String[] args) {
        Computer c = new Computer();
        c.setCpu("i5");
        c.setGpu("gt940mx");
        c.setMemory("16g");
        c.setHd("1T机械");
        System.out.println(c);
    }
}

但是如果是这样的话,我们会发现一些问题:

1.客户端程序员,在实例化好产品的对象之后,必须为该对象的每一个属性赋值,这样对于客户端程序员来说,太麻烦了

2.违反了迪米特法则(即客户端知道的越少越好,尽量已经把电脑配好了)

这相当于你去配电脑,商家把零件全给你,你自己组装电脑!

实现2.0

为了解决这样的问题,我们就新建一个电脑建造类,让这个类来帮我们对属性赋值。

class ComputerBuilder{
    Computer c = new Computer();
    public Computer builder(){
        c.setCpu("i5");
        c.setGpu("gt940mx");
        c.setMemory("16g");
        c.setHd("1T机械");
        return c;
    }
}
public class AppTest2 {
    public static void main(String[] args) {
        ComputerBuilder builder = new ComputerBuilder();
        Computer c = builder.builder();
        System.out.println(c);
    }
}

如果这样做的话,确实解决了上述问题,客户端程序员需要一个产品时,直接向建造者要即可,建造者封装了创建电脑的"复杂"过程,我们就不用进行赋值了,但是这样做仍然有一些问题:封装的太狠了,无论客户的需求是什么,都是采用最高配置,这相当于你去配电脑,无论是什么需求,商家都会给你配置最贵的电脑。

实现3.0

为了解决上述问题,我们新建了三个类AdvancedComputerBuilder,MiddleComputerBuilder,LowComputerBuilder,即高端,中端,低端三个类,这样就可以根据客户端的不同需求,使用不同的建造者来生产产品。

class AdvancedComputerBuilder{
    Computer c = new Computer();
    public Computer builder(){
        c.setCpu("i7");
        c.setGpu("gt940mx");
        c.setMemory("16g");
        c.setHd("5T机械");
        return c;
    }
}
class MiddleComputerBuilder{
    Computer c = new Computer();
    public Computer builder(){
        c.setCpu("i5");
        c.setGpu("gt500mx");
        c.setMemory("8g");
        c.setHd("3T机械");
        return c;
    }
}

class LowComputerBuilder{
    Computer c = new Computer();
    public Computer builder(){
        c.setCpu("i3");
        c.setGpu("gt400mx");
        c.setMemory("4g");
        c.setHd("1T机械");
        return c;
    }
}    

但是仍然是有问题的:

1.我们发现,多个不同的建造者中的代码,在重复!代码出现了重复代码就不好了

2.建造的过程不稳定,如果在某个建造者创建产品的过程中,漏掉了某一步,编译器也不会报错

实现4.0

针对于 3.0的问题,我们使用一个接口来约束电脑建造者,让它必须执行某些步骤,建造者类中的建造过程比较稳定,不会漏掉某一步

interface ComputerBuilder{
    void setCpu();
    void setGpu();
    void setMemory();
    void setHd();
    Computer builder();
}

让那几个建造者全部实现这个接口,这样的话就可以不会漏掉步骤了

class AdvancedComputerBuilder1 implements ComputerBuilder1{

    Computer computer = new Computer();

    @Override
    public void setCpu() {
        computer.setCpu("i7");
    }

    @Override
    public void setGpu() {
        computer.setGpu("gt940mx");
    }

    @Override
    public void setMemory() {
        computer.setMemory("16g");
    }

    @Override
    public void setHd() {
        computer.setHd("5T机械");
    }

    @Override
    public Computer builder() {
        return computer;
    }
}
class MiddleComputerBuilder1 implements ComputerBuilder1{
    Computer computer = new Computer();

    @Override
    public void setCpu() {
        computer.setCpu("i5");
    }

    @Override
    public void setGpu() {
        computer.setGpu("gt500mx");
    }

    @Override
    public void setMemory() {
        computer.setMemory("8g");
    }

    @Override
    public void setHd() {
        computer.setHd("3T机械");
    }

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

class LowComputerBuilder1 implements ComputerBuilder1{

    Computer computer = new Computer();

    @Override
    public void setCpu() {
        computer.setCpu("i3");
    }

    @Override
    public void setGpu() {
        computer.setGpu("gt400mx");
    }

    @Override
    public void setMemory() {
        computer.setMemory("4g");
    }

    @Override
    public void setHd() {
        computer.setHd("1T机械");
    }

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

public class AppTest4 {
    public static void main(String[] args) {
        AdvancedComputerBuilder1 acb = new AdvancedComputerBuilder1();
        MiddleComputerBuilder1 mcb = new MiddleComputerBuilder1();
        LowComputerBuilder1 lcb = new LowComputerBuilder1();
        acb.setCpu();
        acb.setGpu();
        acb.setMemory();
        acb.setHd();
        Computer c1 = acb.builder();
        System.out.println(c1);
    }
}

其实看到这里,又会有新的问题出现了:

代码仍然有重复

现在又变成了客户端自己配置电脑,违反了迪米特法则

目前和第一次相比,就是说自己不用自己去动手挑选零件然后组装,现在只需要自己去指挥干什么,干什么。

而最终的建造者模式就是要解决自己去指挥的功能

实现5.0:建造者模式

我们新建一个指挥类

class Director{
    public Computer builder(ComputerBuilder1 c){
        c.setCpu();
        c.setGpu();
        c.setHd();
        c.setMemory();
        return c.builder();
    }
}

让这个指挥类来帮助我们去指挥,我们只需要得到最后的电脑就行

public class AppTest5 {
    public static void main(String[] args) {
        //游戏
        AdvancedComputerBuilder acb = new AdvancedComputerBuilder();
        //开发
        MiddleComputerBuilder mcb = new MiddleComputerBuilder();
        //办公
        LowComputerBuilder lcb = new LowComputerBuilder();
        Director director = new Director();
        System.out.println(director.builder(acb));
        System.out.println(director.builder(mcb));
        System.out.println(director.builder(lcb));
    }
}

这样就是最后的建造者模式,其实在客户端我们还可以定义更多的电脑建造者,只需实现电脑建造接口,就可以无缝衔接,得到新的电脑

class MiddleHighComputerBuilder implements ComputerBuilder1{

    Computer c =  new Computer();
    @Override
    public void setCpu() {
        c.setCpu("i5 8500h");
    }

    @Override
    public void setGpu() {
        c.setGpu("dfg");
    }

    @Override
    public void setMemory() {
        c.setMemory("wew");
    }

    @Override
    public void setHd() {
        c.setHd("rg");
    }

    @Override
    public Computer builder() {
        return c;
    }
}
public class AppTest5 {
    public static void main(String[] args) {
        //中等偏上配置电脑
        MiddleHighComputerBuilder mhcb = new MiddleHighComputerBuilder();
        Director director = new Director();
        System.out.println(director.builder(mhcb));
    }
}

最终的建造者模式可以自己扩展任意场景的电脑建造者(符合开闭原则),其实对比抽象工厂,工厂模式更侧重于生产,而建造者模式侧重于生产的过程,就行工厂模式讲的汉堡包一样,只是生产汉堡包,而没有去了解汉堡包的原料,建造者就更具侧重于建造的过程。

结语

可能由于自身的水平限制,可能本篇文章有一些问题,还烦请大家谅解,同时希望大家能够有一些建议给我,无论是哪一方面的,谢谢大家!

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一只小猪~~~

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值