建造者模式的应用

街酒 / 2023-05-04 / 原文

案例背景

计算机组装工厂可以将 CPU,内存,硬盘,主机,显示器等硬件设备组装在一起构成一台完整的计算 机,且构成的计算机可以是笔记本电脑,也可以是台式机,还可以是不提供显示器的服务器主机。对于用 户来言,无需关心计算机的组成设备和组装过程,工厂返回给用户的是完整的计算机对象。所以我们可以 使用建造者模式来实现计算机的组成过程,请绘制出类图并编程实现

实现步骤

  • 根据题意,使用建造者模式并画出类图。类图中应包含抽象建造者类 ComputerBuilder,复合产品 类 Computer,具体建造者类 Notebook,Desktop 和 Server,其中台式机和服务器主机使用相同的 CPU,内存,硬盘和主机,但是服务器不包含显示器,而笔记本使用自己独自的一套硬件设备。 此外还需要指挥者类 ComputerAssembleDirector,此类中应有将硬件设备组合在一起的建造方法 assemble()并返回用户需要的具体计算机
  • 根据类图,实现上述类的具体代码以及用户类 Client 和辅助类 XMLUtil 以实现通过 XML 文件来制造不同的计算机
  • 更改 XML 中的属性,观察用户类是否能够获取到不同的计算机以及这些计算机的组装是否符合要求

案例总结

建造者模式主要运用于:

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

UML类图

image

详细代码

抽象建造者类
public abstract class ComputerBuilder {

    protected Computer computer = new Computer();

    public abstract void play();
    public abstract void buildCpus();
    public abstract void buildDisplay();
    public abstract void buildHardware();
    public Computer getComputer(){
        return computer;
    }

}

Notebook类

public class Notebook extends ComputerBuilder{
    @Override
    public void play() {
        System.out.println("2020006924配置笔记本");
    }
    @Override
    public void buildCpus() {
        computer.setCpus("null");
    }
    @Override
    public void buildDisplay() {
        computer.setDisplay("null");
    }

    @Override
    public void buildHardware() {
        computer.setHarware("笔记本独自的硬件设备");
    }
}
Desktop类


public class Desktop extends ComputerBuilder{
    @Override
    public void play() {
        System.out.println("2020006924配置台式机");
    }
    @Override
    public void buildCpus() {
        computer.setCpus("CPU,内存,硬盘和主机");
    }
    @Override
    public void buildDisplay() {
        computer.setDisplay("显示器");
    }
    @Override
    public void buildHardware() {
        computer.setHarware("null");
    }
}
Server类
public class Server extends ComputerBuilder{
    @Override
    public void play() {
        System.out.println("2020006924配置服务器");
    }
    @Override
    public void buildCpus() {
        computer.setCpus("CPU,内存,硬盘和主机");
    }
    @Override
    public void buildDisplay() {
        computer.setDisplay("null");
    }
    @Override
    public void buildHardware() {
        computer.setHarware("null");
    }
}

指挥者类
public class ComputerAssembleDirector {
    private ComputerBuilder cb;
    public void setCb(ComputerBuilder cb){
        this.cb=cb;
    }
    public Computer assemble(){
        cb.play();
        cb.buildCpus();
        cb.buildDisplay();
        cb.buildHardware();
        return cb.getComputer();
    }
}

Computer
public class Computer {
    private String cpus;
    private String display;
    private String harware;
    public String getCpus() {
        return cpus;
    }
    public void setCpus(String cpus) {
        this.cpus = cpus;
    }
    public String getDisplay() {
        return display;
    }
    public void setDisplay(String display) {
        this.display = display;
    }
    public String getHarware() {
        return harware;
    }
    public void setHarware(String harware) {
        this.harware = harware;
    }
}

测试代码
public class Client {
    public static void main(String[] args) {
        try{
            ComputerBuilder cb = (ComputerBuilder) XMLUtil.getBean();
            ComputerAssembleDirector director = new ComputerAssembleDirector();
            director.setCb(cb);
            Computer computer = director.assemble();
            System.out.println(computer.getCpus());
            System.out.println(computer.getDisplay());
            System.out.println(computer.getHarware());
        }catch (Exception e){
            System.out.println(e.getMessage());
        }
    }
}

实验结果

image