设计模式(11):JAVA(11):设计模式(4)建造者模式

例1:

package com.woniuxy.k_builder.a;

// 需求:用户买电脑.

class Computer {
    private String cpu;
    private String memery;
    private String harddisk;
    private String gpu;
    public void setCpu(String cpu) {
        this.cpu = cpu;
    }
    public void setMemery(String memery) {
        this.memery = memery;
    }
    public void setHarddisk(String harddisk) {
        this.harddisk = harddisk;
    }
    public void setGpu(String gpu) {
        this.gpu = gpu;
    }
    @Override
    public String toString() {
        return "Computer [cpu=" + cpu + ", memery=" + memery + ", harddisk=" + harddisk + ", gpu=" + gpu + "]";
    }
}

public class Test {
    public static void main(String[] args) {
        Computer c = new Computer();
        
        c.setCpu("i7 7700hq");
        c.setMemery("16");
        c.setHarddisk("1T");
        c.setGpu("Rtx2080ti");
        
        System.out.println(c);
        
    }
}

// 缺点:
// 1. 当一个对象的组成过程特别繁琐,特别麻烦的时候,就不应该让客户端自己来完成。(相当于你去配电脑,卖家把所有组件都给你摆出来,让你自己亲自动手组装)。
// 2. 这样客户端可能会不按正确步骤组装对象,或缺少了某一个组件。
// 3. 这样违反了迪米特法则


// 对比,工厂模式,都是只负责把对象直接实例化出来,不管对象的状态。  建造者特强侧重于把对象new出来以后,给对象的属性赋值!

例2

package com.woniuxy.k_builder.b;

// 针对于a包的缺点,重构代码如下:
// 1. 作者额外添加一个功能:直接封装装配电脑的工作。

class Computer {
    private String cpu;
    private String memery;
    private String harddisk;
    private String gpu;
    public void setCpu(String cpu) {
        this.cpu = cpu;
    }
    public void setMemery(String memery) {
        this.memery = memery;
    }
    public void setHarddisk(String harddisk) {
        this.harddisk = harddisk;
    }
    public void setGpu(String gpu) {
        this.gpu = gpu;
    }
    @Override
    public String toString() {
        return "Computer [cpu=" + cpu + ", memery=" + memery + ", harddisk=" + harddisk + ", gpu=" + gpu + "]";
    }
}

class ComputerBuilder {
    private Computer c = new Computer();
    
    public Computer build() {
        c.setCpu("i7 7700hq");
        c.setMemery("16");
        c.setHarddisk("1T");
        c.setGpu("Rtx2080ti");
        return c;
    }
}

// ==================================================================

public class Test {
    public static void main(String[] args) {
        ComputerBuilder cb = new ComputerBuilder();
        
        // 学习 (cpu好 + 内存 )
        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. 封装地太狠! 无论客户端是什么需求,客户端没办法选择配置! 都是由服务器端定死的配置!!



// 应该根据不同需求,配置出不同的 低端、中端、高端电脑.

例3

package com.woniuxy.k_builder.c;

// 针对于b包的缺点,重构代码如下:

// 1. 针对于不同需求,有不同的建造者。
// 2. 客户端仍然不知道建造电脑的过程。

class Computer {
    private String cpu;
    private String memery;
    private String harddisk;
    private String gpu;
    public void setCpu(String cpu) {
        this.cpu = cpu;
    }
    public void setMemery(String memery) {
        this.memery = memery;
    }
    public void setHarddisk(String harddisk) {
        this.harddisk = harddisk;
    }
    public void setGpu(String gpu) {
        this.gpu = gpu;
    }
    @Override
    public String toString() {
        return "Computer [cpu=" + cpu + ", memery=" + memery + ", harddisk=" + harddisk + ", gpu=" + gpu + "]";
    }
}

class AdvancedComputerBuilder {
    private Computer c = new Computer();
    
    public Computer build() {
        c.setCpu("i9 8700hk");
        c.setMemery("64");
        c.setHarddisk("2T+512固态硬盘");
        c.setGpu("双卡交火 Rtx2080ti");
        return c;
    }
}

class MiddleComputerBuilder {
    private Computer c = new Computer();
    
    public Computer build() {
        c.setCpu("i7 7700hq");
        c.setMemery("16");
        c.setHarddisk("1T+256固态");
        c.setGpu("GTX1070");
        return c;
    }
}

class LowComputerBuilder {
    private Computer c = new Computer();
    
    public Computer build() {
        c.setCpu("i5 3320m");
        c.setMemery("8");
        c.setHarddisk("500g");
        c.setGpu("集成显卡");
        return c;
    }
}


// ==================================================================

public class Test {
    public static void main(String[] args) {
        AdvancedComputerBuilder acb = new AdvancedComputerBuilder();
        MiddleComputerBuilder mcb = new MiddleComputerBuilder();
        LowComputerBuilder lcb = new LowComputerBuilder();
        
        // 学习
        Computer c = mcb.build();
        System.out.println(c);
        
        // 办公、娱乐
        Computer c2 = lcb.build();
        System.out.println(c2);
                
                
        // 游戏
        Computer c3 = acb.build();
        System.out.println(c3);
    }
}

// 缺点:
// 1. 无论是高 中 低哪一种配置的电脑,配置的过程都是一样的,只不过细节不一样。 既然有重复,那就有了坏味道。
// 2. 这些重复的安装步骤,不稳定,万一哪一个建造者中漏了某一个步骤,编译期也不会报错!

例4

package com.woniuxy.k_builder.d;

// 针对于c包的缺点,重构代码如下:

// 1. 稳定住,建造电脑的过程, 定义一个建造者接口
// 2. 让所有具体建造者实现这个接口,那么所有具体建造者,就必须实现这个接口中的所有方法,就不会遗漏某一个步骤。
interface ComputerBuilder {
    void setCpu();
    void setMemery();
    void setHarddisk();
    void setGpu();
    
    Computer build();
}


class Computer {
    private String cpu;
    private String memery;
    private String harddisk;
    private String gpu;
    public void setCpu(String cpu) {
        this.cpu = cpu;
    }
    public void setMemery(String memery) {
        this.memery = memery;
    }
    public void setHarddisk(String harddisk) {
        this.harddisk = harddisk;
    }
    public void setGpu(String gpu) {
        this.gpu = gpu;
    }
    @Override
    public String toString() {
        return "Computer [cpu=" + cpu + ", memery=" + memery + ", harddisk=" + harddisk + ", gpu=" + gpu + "]";
    }
    
}

class AdvancedComputerBuilder implements ComputerBuilder{
    private Computer c = new Computer(); 
    @Override
    public void setCpu() {
        c.setCpu("i9 8700hk");
    }
    @Override
    public void setMemery() {
        c.setMemery("64g");
    }
    @Override
    public void setHarddisk() {
        c.setHarddisk("2T + 515固态");
    }
    @Override
    public void setGpu() {
        c.setGpu("rtx2080ti");
    }
    @Override
    public Computer build() {
        return c;
    }
}

class MiddleComputerBuilder implements ComputerBuilder{
    private Computer c = new Computer(); 
    @Override
    public void setCpu() {
        c.setCpu("i7 7700hq");
    }
    @Override
    public void setMemery() {
        c.setMemery("16g");
    }
    @Override
    public void setHarddisk() {
        c.setHarddisk("1T + 256固态");
    }
    @Override
    public void setGpu() {
        c.setGpu("gtx1070");
    }
    @Override
    public Computer build() {
        return c;
    }
}

class LowComputerBuilder implements ComputerBuilder{
    private Computer c = new Computer(); 
    @Override
    public void setCpu() {
        c.setCpu("i5 3320m");
    }
    @Override
    public void setMemery() {
        c.setMemery("8");
    }
    @Override
    public void setHarddisk() {
        c.setHarddisk("500g");
    }
    @Override
    public void setGpu() {
        c.setGpu("集成显卡");
    }
    @Override
    public Computer build() {
        return c;
    }
}



// ==================================================================

public class Test {
    public static void main(String[] args) {
        
        AdvancedComputerBuilder acb = new AdvancedComputerBuilder();
        acb.setCpu();
        acb.setHarddisk();
        acb.setMemery();
        acb.setGpu();
        Computer c = acb.build();
        System.out.println(c);
        
        
        MiddleComputerBuilder mcb = new MiddleComputerBuilder();
        mcb.setCpu();
        mcb.setHarddisk();
        mcb.setMemery();
        mcb.setGpu();
        Computer c2 = mcb.build();
        System.out.println(c2);
    }
}

// 缺点:
// 1. 客户端又必须知道建造的过程了, (相当于你去配一台电脑,虽然不是自己亲自组装电脑,但是你要只会那个“小伙”,该装...该装...该装...)

例5:

package com.woniuxy.k_builder.e;

// 针对于d包的缺点,重构代码如下:

// 1. 创建一个指挥者(Director),接受不同的建造者,完成建造过程


interface ComputerBuilder {
    void setCpu();
    void setMemery();
    void setHarddisk();
    void setGpu();
    Computer build();
}


class Computer {
    private String cpu;
    private String memery;
    private String harddisk;
    private String gpu;
    public void setCpu(String cpu) {
        this.cpu = cpu;
    }
    public void setMemery(String memery) {
        this.memery = memery;
    }
    public void setHarddisk(String harddisk) {
        this.harddisk = harddisk;
    }
    public void setGpu(String gpu) {
        this.gpu = gpu;
    }
    @Override
    public String toString() {
        return "Computer [cpu=" + cpu + ", memery=" + memery + ", harddisk=" + harddisk + ", gpu=" + gpu + "]";
    }
}

class AdvancedComputerBuilder implements ComputerBuilder{
    private Computer c = new Computer(); 
    @Override
    public void setCpu() {
        c.setCpu("i9 8700hk");
    }
    @Override
    public void setMemery() {
        c.setMemery("64g");
    }
    @Override
    public void setHarddisk() {
        c.setHarddisk("2T + 515固态");
    }
    @Override
    public void setGpu() {
        c.setGpu("rtx2080ti");
    }
    @Override
    public Computer build() {
        return c;
    }
}

class MiddleComputerBuilder implements ComputerBuilder{
    private Computer c = new Computer(); 
    @Override
    public void setCpu() {
        c.setCpu("i7 7700hq");
    }
    @Override
    public void setMemery() {
        c.setMemery("16g");
    }
    @Override
    public void setHarddisk() {
        c.setHarddisk("1T + 256固态");
    }
    @Override
    public void setGpu() {
        c.setGpu("gtx1070");
    }
    @Override
    public Computer build() {
        return c;
    }
}

class LowComputerBuilder implements ComputerBuilder{
    private Computer c = new Computer(); 
    @Override
    public void setCpu() {
        c.setCpu("i5 3320m");
    }
    @Override
    public void setMemery() {
        c.setMemery("8");
    }
    @Override
    public void setHarddisk() {
        c.setHarddisk("500g");
    }
    @Override
    public void setGpu() {
        c.setGpu("集成显卡");
    }
    @Override
    public Computer build() {
        return c;
    }
}


class Director {
    public Computer build(ComputerBuilder cb) {
        cb.setCpu();
        cb.setHarddisk();
        cb.setMemery();
        cb.setGpu();
        return cb.build();
    }
}



// ==================================================================

public class Test {
    public static void main(String[] args) {
        
        AdvancedComputerBuilder acb = new AdvancedComputerBuilder();
        MiddleComputerBuilder mcb = new MiddleComputerBuilder();
        
        Director director = new Director();
        Computer c = director.build(mcb);
        
        System.out.println(c);
    }
}


// 至此,建造者设计模式的第一种形态,推演完毕!

// 该形态的缺点是,客户端无法灵活控制组件的细节,比如,客户端无法直接指定cpu或者硬盘的型号。
// 所以才有了建造者模式的第二种形态,而第二种形态又不仅仅是解决以上提到的问题的。

设计模式(11):JAVA(11):设计模式(4)建造者模式

 

 例6:

package com.woniuxy.k_builder.f;

import com.woniuxy.k_builder.f.Computer.ComputerBuilder;

// 当一个类的属性特别多的时候,构造器的参数也就特别多,尤其是构造器的多个参数类型还都一样。
// 那么客户端代码就很容易出错。

class Computer {
    private String cpu;
    private String harddisk;
    private String memery;
    private String gpu;
    private String power;
    private String motherboard; // 主板
    private String cdrom;
    private String fan;
    private String netcard;
//    public Computer(String cpu, String harddisk, String memery, String gpu, String power, String motherboard,
//            String cdrom, String fan, String netcard) {
//        super();
//        this.cpu = cpu;
//        this.harddisk = harddisk;
//        this.memery = memery;
//        this.gpu = gpu;
//        this.power = power;
//        this.motherboard = motherboard;
//        this.cdrom = cdrom;
//        this.fan = fan;
//        this.netcard = netcard;
//    }
    
    public Computer() {
    }
    
    private Computer(ComputerBuilder cb) {
        this.cpu = cb.cpu;
        this.harddisk = cb.harddisk;
        this.memery = cb.memery;
        this.gpu = cb.gpu;
        this.power = cb.power;
        this.netcard = cb.netcard;
        this.motherboard = cb.motherboard;
        this.fan = cb.fan;
        this.cdrom = cb.cdrom;
    }
    
    // 以上的构造器,使用起来确实很麻烦! 也许有小伙伴会这样向,我们可以对构造器进行重载,把参数减少, 事实证明,这也很2....
    
    // 最好的解决方法是使用建造这设计模式的第二种形态
    // 1. 建造者必须是产品的一个静态内部类
    // 2. 建造者的属性完全与产品的所有属性一致
    // 3. 为建造者的每一个属性都添加一个setter方法,且该setter方法必须返回建造者对象本身
    // (以前的javabean的setter方法,返回值是void)
    
    public static class ComputerBuilder {
        private String cpu;
        private String harddisk;
        private String memery;
        private String gpu;
        private String power;
        private String motherboard; // 主板
        private String cdrom;
        private String fan;
        private String netcard;
        public ComputerBuilder setCpu(String cpu) {
            this.cpu = cpu;
            return this;
        }
        public ComputerBuilder setHarddisk(String harddisk) {
            this.harddisk = harddisk;
            return this;
        }
        public ComputerBuilder setMemery(String memery) {
            this.memery = memery;
            return this;
        }
        public ComputerBuilder setGpu(String gpu) {
            this.gpu = gpu;
            return this;
        }
        public ComputerBuilder setPower(String power) {
            this.power = power;
            return this;
        }
        public ComputerBuilder setMotherboard(String motherboard) {
            this.motherboard = motherboard;
            return this;
        }
        public ComputerBuilder setCdrom(String cdrom) {
            this.cdrom = cdrom;
            return this;
        }
        public ComputerBuilder setFan(String fan) {
            this.fan = fan;
            return this;
        }
        public ComputerBuilder setNetcard(String netcard) {
            this.netcard = netcard;
            return this;
        }
        
        public Computer build() {
            System.out.println("组装" + cpu + "," + gpu + "," + memery);
            return new Computer(this);
        }
    }

    @Override
    public String toString() {
        return "Computer [cpu=" + cpu + ", harddisk=" + harddisk + ", memery=" + memery + ", gpu=" + gpu + ", power="
                + power + ", motherboard=" + motherboard + ", cdrom=" + cdrom + ", fan=" + fan + ", netcard=" + netcard
                + "]";
    }

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

    public void setHarddisk(String harddisk) {
        this.harddisk = harddisk;
    }

    public void setMemery(String memery) {
        this.memery = memery;
    }

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

    public void setPower(String power) {
        this.power = power;
    }

    public void setMotherboard(String motherboard) {
        this.motherboard = motherboard;
    }

    public void setCdrom(String cdrom) {
        this.cdrom = cdrom;
    }

    public void setFan(String fan) {
        this.fan = fan;
    }

    public void setNetcard(String netcard) {
        this.netcard = netcard;
    }
    
}


public class Test {
    public static void main(String[] args) {
        ComputerBuilder cb = new ComputerBuilder();
        Computer c = cb.setMotherboard("华硕主板").setCpu("酷睿8代").setFan("cpu自带的风扇").setHarddisk("500g").build();
        System.out.println(c);
    }
}

// 建造者设计模式的第二种形态: 参考effective java 第二条2 :当类的属性过多时,就使用建造者设计模式的第二种形态  

 

设计模式(11):JAVA(11):设计模式(4)建造者模式

上一篇:SaaS方式运行jar


下一篇:七个错误可能引发网页布局灾难