设计模式之构建者(创建者builder)模式

写在前面

构造者模式将一个复杂对象的构造过程和它的表现层分离开来,使得相同的构建过程能够创建不同的表示

主要运用在复杂类的创建上

 

示例

现在有一个Computer类,Computer又由CPU,Disk,Memory等类组成。

Computer类

package com.zl.builder;

public class Computer {
    public CPU cpu;
    public Disk disk;
    public Memory memory;

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

CPU类

package com.zl.builder;

public class CPU {
    private String manufacturers;//生产商
    private String generation;//第几代
    private String frequency;//频率

    public CPU(String manufacturers, String generation, String frequency) {
        this.manufacturers = manufacturers;
        this.generation = generation;
        this.frequency = frequency;
    }

    @Override
    public String toString() {
        return "CPU{" +
                "manufacturers='" + manufacturers + '\'' +
                ", generation='" + generation + '\'' +
                ", frequency='" + frequency + '\'' +
                '}';
    }
}

Disk类

package com.zl.builder;

public class Disk {
    private String manufacturers;//生产商
    private String specification;//型号
    private String readSpeed;//读取速度
    private String writeSpeed;//写入速度

    public Disk(String manufacturers, String specification, String readSpeed, String writeSpeed) {
        this.manufacturers = manufacturers;
        this.specification = specification;
        this.readSpeed = readSpeed;
        this.writeSpeed = writeSpeed;
    }

    @Override
    public String toString() {
        return "Disk{" +
                "manufacturers='" + manufacturers + '\'' +
                ", specification='" + specification + '\'' +
                ", readSpeed='" + readSpeed + '\'' +
                ", writeSpeed='" + writeSpeed + '\'' +
                '}';
    }
}

Memory类

package com.zl.builder;

public class Memory {
    private String manufacturers;//生产商
    private String capacity;//容量
    private String frequency;//内存频率

    public Memory(String manufacturers, String capacity, String frequency) {
        this.manufacturers = manufacturers;
        this.capacity = capacity;
        this.frequency = frequency;
    }

    @Override
    public String toString() {
        return "Memory{" +
                "manufacturers='" + manufacturers + '\'' +
                ", capacity='" + capacity + '\'' +
                ", frequency='" + frequency + '\'' +
                '}';
    }
}

 为了构建一个Computer类,再来一个builder接口

(注意,方法返回不为空而是ComputerBuilder ,链式编程为了方便使用)

package com.zl.builder;

public interface ComputerBuilder {
    ComputerBuilder builderCPU(CPU cpu);
    ComputerBuilder builderDisk(Disk disk);
    ComputerBuilder builderMemory(Memory memory);
    Computer builderComputer();
}

 CommonComputerBuilder,普通电脑构建器,实现ComputerBulider接口

package com.zl.builder;

public class CommonComputerBuilder implements ComputerBuilder{
    Computer computer = new Computer();
    @Override
    public ComputerBuilder builderCPU(CPU cpu) {
        computer.cpu = cpu;
        return this;
    }

    @Override
    public ComputerBuilder builderDisk(Disk disk) {
        computer.disk = disk;
        return this;
    }

    @Override
    public ComputerBuilder builderMemory(Memory memory) {
        computer.memory = memory;
        return this;
    }

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

最后Main类测试

package com.zl.builder;

public class Main {
    public static void main(String[] args) {
        ComputerBuilder computerBuilder = new CommonComputerBuilder();
        Computer computer = computerBuilder.builderCPU(new CPU("intel", "10代酷睿", "4.0Ghz"))
                .builderDisk(new Disk("西部数据", "黑盘SN750", "3.4G/s", "1.7G/s"))
                .builderMemory(new Memory("海盗船", "16G", "3200Mhz"))
                .builderComputer();
        
        System.out.println(computer);
    }
}

输出:

 

 

到这,有些人会说,咋这么费劲呢,直接来一个Computer的构造方法(public Computer(CPU cpu, Disk disk, Memory memory){...})不就完事了

嗯......好像确实是这样,俗话说“设无定法,各有千秋”

 

示例二

People类,拥有非常多属性,几十个,甚至上百个。

有些时候只会用到其中的某几个。

People类

(在这里,私有化构造方法,植入静态内部类,分组构建People属性)

 

package com.zl.builder.v2;

public class People {
    String name;
    Integer age;
    String sex;

    String tel;
    String height;
    String weight;
    String birthday;

    Address address;

    String father;
    String mother;


    private People(){}

    public static class PeopleBuilder{
        People p = new People();

        public PeopleBuilder baseInfoBuilder(String name, Integer age, String sex){
            p.name = name;
            p.age = age;
            p.sex = sex;
            return this;
        }

        public PeopleBuilder detailBuilder(String tel, String birthday, String height, String weight){
            p.tel = tel;
            p.birthday = birthday;
            p.height = height;
            p.weight = weight;
            return this;
        }

        public PeopleBuilder addressBuilder(Address address){
            p.address = address;
            return this;
        }

        public PeopleBuilder otherBuilder(String father, String mother){
            p.father = father;
            p.mother = mother;
            return this;
        }

        public People builder(){
            return p;
        }
    }

    @Override
    public String toString() {
        return "People{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", sex='" + sex + '\'' +
                ", tel='" + tel + '\'' +
                ", height='" + height + '\'' +
                ", weight='" + weight + '\'' +
                ", birthday='" + birthday + '\'' + "\n" +
                ", address=" + address +
                ", father='" + father + '\'' +
                ", mother='" + mother + '\'' +
                '}';
    }
}

 

其中People中用到的Address类

package com.zl.builder.v2;

public class Address {
    String Province;
    String detail;

    public Address(String province, String detail) {
        Province = province;
        this.detail = detail;
    }

    @Override
    public String toString() {
        return "Address{" +
                "Province='" + Province + '\'' +
                ", detail='" + detail + '\'' +
                '}';
    }
}

Main测试类(如果只需要构建一部分属性,根据构建部分分组builder即可)

package com.zl.builder.v2;

public class Main {
    public static void main(String[] args) {
        People people = new People.PeopleBuilder()
                .baseInfoBuilder("张三", 22, "男")
                .detailBuilder("13566668888", "3-7", "180cm", "60kg")
                //.otherBuilder("XXX", "XXX")
                .addressBuilder(new Address("湖南长沙", "某某区某某街"))
                .builder();

        System.out.println(people);
    }
}

输出:

 

posted @ 2020-09-29 15:43  风子磊  阅读(199)  评论(0编辑  收藏  举报