设计模式之建造者模式

建造者模式

  • 逐步推导建造者模式的由来
  • 需求:
    • 定义一个电脑类,并且实例化出电脑类的对象,以及给该对象的属性赋值

  • 未使用建造者模式
class Computer {
    private String cpu;
    private String gpu;
    private String memory;
    private String hd;

    public String getCpu() {
        return cpu;
    }

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

    public String getGpu() {
        return gpu;
    }

    public void setGpu(String gpu) {
        this.gpu = gpu;
    }

    public String getMemory() {
        return memory;
    }

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

    public String getHd() {
        return hd;
    }

    public void setHd(String hd) {
        this.hd = hd;
    }

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

//=======================时空线=============================
//=========上面为服务端(提供服务,作者),下面为客户端(使用服务)=====

public class AppTest {

    public static void main(String[] args) {
        Computer c = new Computer();
        c.setCpu("i7 7500u");
        c.setGpu("gt940mx");
        c.setMemory("16g");
        c.setHd("1T机械");

        System.out.println(c);
    }
}
  • 这样做的缺点:
    1. 客户端程序猿在实例化好产品的对象之后,必须为该对象的每一个属性赋值,这样对客户端程序猿来说,太麻烦了!
    2. 违反了迪米特法则(最少知道原则), 客户端程序猿知道得太多了
    • 这相当于你去配置电脑,商家把零件全给你,你自己组装电脑!

  • 针对上面两个问题,修改代码如下:
    • 作者,专门创建一个"ComputerBuilder" 类,这个类专门封装组装电脑的过程
class Computer {
    private String cpu;
    private String gpu;
    private String memory;
    private String hd;

    public String getCpu() {
        return cpu;
    }

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

    public String getGpu() {
        return gpu;
    }

    public void setGpu(String gpu) {
        this.gpu = gpu;
    }

    public String getMemory() {
        return memory;
    }

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

    public String getHd() {
        return hd;
    }

    public void setHd(String hd) {
        this.hd = hd;
    }

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

// 电脑建造者,建造者类,必须关联电脑产品
class ComputerBuilder {
    private Computer computer = new Computer();

    public Computer build() {
        computer.setCpu("i7 8750HK");
        computer.setGpu("rtx2080Ti");
        computer.setMemory("32g");
        computer.setHd("500g固态+2T机械");
        return computer;
    }
}

//=======================时空线=============================
//=========上面为服务端(提供服务,作者),下面为客户端(使用服务)=====
public class AppTest {

    public static void main(String[] args) {

       //创建一个建造者
        ComputerBuilder cb = new ComputerBuilder();

        //玩游戏
        Computer c = cb.build();
        System.out.println(c);

        //开发
        Computer c2 = cb.build();
        System.out.println(c2);

        //办公娱乐
        Computer c3 = cb.build();
        System.out.println(c3);
    }
}
  • 目前的这种写法还不是建造模式
    • 目前的优点:
      1. 客户端程序猿需要一个产品时,直接向建造者要即可,建造者封装了创建电脑的"复杂"过程
    • 目前的缺点:
      1. 封装得太狠了!无论客户得需求什么,都是采用最高配置,这相当于你去配电脑,无论是什么需求,商家都会给你配最贵的电脑!

  • 针对封装得太狠了的问题,修改代码如下:
    • 针对于不同需求,我们需要创建不同的建造者,来分别生产不同
class Computer {
    private String cpu;
    private String gpu;
    private String memory;
    private String hd;

    public String getCpu() {
        return cpu;
    }

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

    public String getGpu() {
        return gpu;
    }

    public void setGpu(String gpu) {
        this.gpu = gpu;
    }

    public String getMemory() {
        return memory;
    }

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

    public String getHd() {
        return hd;
    }

    public void setHd(String hd) {
        this.hd = hd;
    }

    @Override
    public String toString() {
        return "Computer{" +
                "cpu='" + cpu + '\'' +
                ", gpu='" + gpu + '\'' +
                ", memory='" + memory + '\'' +
                ", hd='" + hd + '\'' +
                '}';
    }
}
//高配
class AdvancedComputerBuilder {

    private Computer computer = new Computer();

    public Computer build() {
        computer.setCpu("i7 8750HK");
        computer.setGpu("rtx2080Ti");
        computer.setMemory("32g");
        computer.setHd("500g固态+2T机械");
        return computer;
    }
}

//中配
class MiddleComputerBuilder {

    private Computer computer = new Computer();

    public Computer build() {
        computer.setCpu("i7 7700hq");
        computer.setGpu("gtx1060");
        computer.setMemory("16g");
        computer.setHd("250g固态+1T机械");
        return computer;
    }
}

//低配
class LowComputerBuilder {

    private Computer computer = new Computer();

    public Computer build() {
        computer.setCpu("i7 7500u");
        computer.setGpu("gtx940mx");
        computer.setMemory("8g");
        computer.setHd("1T机械");
        return computer;
    }
}

//=======================时空线=============================
//=========上面为服务端(提供服务,作者),下面为客户端(使用服务)=====
public class AppTest {

    public static void main(String[] args) {

        AdvancedComputerBuilder adc = new AdvancedComputerBuilder();
        MiddleComputerBuilder mcb = new MiddleComputerBuilder();
        LowComputerBuilder lcb = new LowComputerBuilder();

        //玩游戏
        Computer c = adc.build();
        System.out.println(c);

        //开发
        Computer c2 = mcb.build();
        System.out.println(c2);

        //办公娱乐
        Computer c3 = mcb.build();
        System.out.println(c3);


    }
}

  • 这任然不是建造者模式:
    • 优点:
      1. 可以根据客户端的不同需求, 使用不同的建造者来生产产品
    • 缺点:
      1. 我们发现,多个不同的建造者中的代码,在重复!既然代码中出现了重复的代码,那就有了"坏味道"!
      2. 建造的过程不稳定! 如果在某个建造者创建产品的过程中,漏调了某一步,编译器也不会报错!
        (相当于,KFC的某一家分店,你制作汉堡包的流程突然少了某一步骤,出现的汉堡包味道就变了,因为没有标准!)

  • 针对以上两个问题,修改代码如下:
  • 创建一个建造者接口,把制作产品的具体步骤,稳定下来!
class Computer {
    private String cpu;
    private String gpu;
    private String memory;
    private String hd;

    public String getCpu() {
        return cpu;
    }

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

    public String getGpu() {
        return gpu;
    }

    public void setGpu(String gpu) {
        this.gpu = gpu;
    }

    public String getMemory() {
        return memory;
    }

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

    public String getHd() {
        return hd;
    }

    public void setHd(String hd) {
        this.hd = hd;
    }

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

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

// 电脑建造者,建造者类,必须关联电脑产品

//高配
class AdvancedComputerBuilder implements ComputerBuilder{

    private Computer computer = new Computer();

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

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

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

    @Override
    public void setHd() {
        computer.setHd("500g固态+2T机械");
    }

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

//中配
class MiddleComputerBuilder implements ComputerBuilder{

    private Computer computer = new Computer();

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

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

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

    @Override
    public void setHd() {
        computer.setHd("250g固态+1T机械");
    }

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

//低配
class LowComputerBuilder implements ComputerBuilder{

    private Computer computer = new Computer();

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

    }

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

    }

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

    }

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

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

//=======================时空线=============================
//=========上面为服务端(提供服务,作者),下面为客户端(使用服务)=====

//玩游戏
        AdvancedComputerBuilder acb = new AdvancedComputerBuilder();
        acb.setCpu();
        acb.setGpu();
        acb.setMemory();
        acb.setHd();
        Computer c = acb.build();
        System.out.println(c);

        //开发
        MiddleComputerBuilder mcb = new MiddleComputerBuilder();
        mcb.setCpu();
        mcb.setGpu();
        mcb.setMemory();
        mcb.setHd();
        Computer c2 = mcb.build();
        System.out.println(c2);

        //办公娱乐
        LowComputerBuilder lcb = new LowComputerBuilder();
        lcb.setCpu();
        lcb.setGpu();
        lcb.setMemory();
        lcb.setHd();
        Computer c3 = lcb.build();
        System.out.println(c3);
  • 这还不是建造者模式
    • 优点:
      1. 建造者类中的建造过程是稳定的,不会漏掉某一步!!这样当客户端想扩展建造者时,也不会漏掉某一步
    • 缺点:
      1. 代码任然有重复
      2. 客户端现在又变成了客户端自己配置电脑,又违反了迪米特法则
        (这相当于,去电脑城配电脑,虽然不用你亲自组装电脑,但是你必须"指挥"装机老板,该装什么…该装什么…)

  • 针对代码重复,和违反迪米特法则,修改代码如下:
  • 建造者模式: 终于进化出来了
class Computer {
    private String cpu;
    private String gpu;
    private String memory;
    private String hd;

    public String getCpu() {
        return cpu;
    }

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

    public String getGpu() {
        return gpu;
    }

    public void setGpu(String gpu) {
        this.gpu = gpu;
    }

    public String getMemory() {
        return memory;
    }

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

    public String getHd() {
        return hd;
    }

    public void setHd(String hd) {
        this.hd = hd;
    }

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

//稳点建造过程
interface ComputerBuilder {
    public void setCpu();
    public void setGpu();
    public void setMemory();
    public void setHd();
    public Computer build();
}

//高配
class AdvancedComputerBuilder implements ComputerBuilder {

    private Computer computer = new Computer();

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

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

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

    @Override
    public void setHd() {
        computer.setHd("500g固态+2T机械");
    }

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

//中配
class MiddleComputerBuilder implements ComputerBuilder {

    private Computer computer = new Computer();

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

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

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

    @Override
    public void setHd() {
        computer.setHd("250g固态+1T机械");
    }

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

//低配
class LowComputerBuilder implements ComputerBuilder {

    private Computer computer = new Computer();

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

    }

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

    }

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

    }

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

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

//指挥者 指挥的过程,从客户端分离出来
class Director {

    public Computer build(ComputerBuilder cb) {
        cb.setCpu();
        cb.setGpu();
        cb.setMemory();
        cb.setHd();

        return cb.build();
    }
}

//=======================时空线=============================
//=========上面为服务端(提供服务,作者),下面为客户端(使用服务)=====

public class AppTest {

    public static void main(String[] args) {




        AdvancedComputerBuilder acb = new AdvancedComputerBuilder();
        MiddleComputerBuilder mcb = new MiddleComputerBuilder();
        LowComputerBuilder lcb = new LowComputerBuilder();

        Director director = new Director();

        //玩游戏
        Computer c = director.build(acb);
        System.out.println(c);

        //开发
        Computer c2 = director.build(mcb);
        System.out.println(c2);

        //办公娱乐
        Computer c3 = director.build(lcb);
        System.out.println(c3);

        MiddleHighComputerBuilder mhcb = new MiddleHighComputerBuilder();
        Computer c4 = director.build(mhcb);
        System.out.println(c4);

    }
}

  • 这就是建造者模式
      1. 一个稳点建造过程的接口
      2. 建造者实现建造过程的接口
      3. 创建一个指挥者,把过程交给指挥者就行了
    • 优点:
      1. 创建对象的工厂是稳定不变的(因为有ComputerBuilder接口来稳定过程)
      2. 创建对象的过程只写了一次,没有重复代码(指挥者完成)
      3. 当需要扩展指挥者的时候,不用修改之前的代码,这符合开闭原则

在这里插入图片描述


建造者与工厂模式的区别:
  • 工厂模式:
    • 工厂模式只需要一个简单的new,new出产品即可.
  • 建造者模式:
    • 建造者更注重在new出产品之后的,为产品属性赋值的过程!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值