关于设计模式:设计模式第四篇建造者模式也没那么难

3次阅读

共计 5222 个字符,预计需要花费 14 分钟才能阅读完成。

一 引言

阐明:如果想要间接浏览定义等实践内容,能够间接跳转到第二大点

在生活中有很多场景与咱们明天要说的“建造者模式”是十分匹配的,打个比方一台计算机是由 CPU、内存、显卡、内存、鼠标、键盘、显示器等等内容组合而成的,咱们想要一台电脑,咱们不会可能本人去做这些配件,个别都是通过通知销售公司,而后其派生产技术人员给你做好指定的配件。

先不论,谁买,谁做,谁治理的问题,咱们能够剖析失去,建造电脑的这个 “过程”是稳固的 也就是说,不论什么配置的电脑,这些配件都是必须要有的,只是 具体的细节不一样,例如你的配置更好,他的差一些

然而,我作为一个买家,我并不想管这些,我只通知你,我要一台中等配置的电脑,你负责“建造”好给我就行了,这就是建造者模式比拟艰深的讲法

上面咱们通过这个计算机的例子,循序渐进的看一下:

二 通过例子循序渐进意识建造者模式

首先,不管怎么建,怎么买,一个 Computer 电脑类是必须的,咱们轻易筛选三个组件来进行演示,CPU、内存、显示器,补充其 get set toString 办法

/**
 * 产品:电脑
 */
public class Computer {
    private String cpu; // CPU
    private String graphicsCard; // 内存
    private String displayScreen; // 显示器

    public String getCpu() {return cpu;}

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

    public String getGraphicsCard() {return graphicsCard;}

    public void setGraphicsCard(String graphicsCard) {this.graphicsCard = graphicsCard;}

    public String getDisplayScreen() {return displayScreen;}

    public void setDisplayScreen(String displayScreen) {this.displayScreen = displayScreen;}
    
    @Override
    public String toString() {
        return "Computer{" +
                "cpu='" + cpu + '\'' +
                ", graphicsCard='" + graphicsCard + '\'' +
                ", displayScreen='" + displayScreen + '\'' +
                '}';
    }
}

(一) 最简略直白的形式(不好)

这种办法根本能够说没什么技术含量了,间接 new + set 就行了

public class Test {public static void main(String[] args) {Computer computer = new Computer();
        computer.setCpu("英特尔酷睿 i5 处理器");
        computer.setGraphicsCard("4g 内存");
        computer.setDisplayScreen("14 寸 1080p 60hz 显示器");
        System.out.println(computer.toString());
    }
}

打印一下后果:

Computer{cpu=’ 英特尔酷睿 i5 处理器 ’, graphicsCard=’4g’, displayScreen=’14 寸 1080p 60hz 显示器 ’}

(二) 客户间接分割生产技术人员

下面这种形式,不用说也晓得不适合了,所以技术人员(建造者)他来了!然而不同的技术人员会制作的配件也不一样,例如有的会做 144hz 的显示器,而有的专攻 60hz 的显示器,有高下配置,不同型号之分

为此咱们为其形象出一个 ComputerBuilder 的抽象类

/**
 * 电脑的建造者
 */
public abstract class ComputerBuilder {abstract void buildCpu(); // 建造 CPU
    abstract void buildGraphicsCard(); // 建造内存
    abstract void buildDisplayScreen(); // 建造显示器

    abstract Computer getComputer(); // 拿到这台电脑}

上面就来写建造者的具体实现,例如先写一个低配置电脑建造的实现

/**
 * 低配置电脑
 */
public class LowConfigurationComputerBuilder extends ComputerBuilder {

    private Computer computer;

    public LowConfigurationComputerBuilder(){computer = new Computer();
    }

    @Override
    void buildCpu() {computer.setCpu("英特尔酷睿 i5 处理器");
        System.out.println("buildCpu: 英特尔酷睿 i5 处理器");
    }

    @Override
    void buildGraphicsCard() {computer.setGraphicsCard("8g 内存");
        System.out.println("buildGraphicsCard: 8g 内存");
    }

    @Override
    void buildDisplayScreen() {computer.setDisplayScreen("1080p 60hz 显示器");
        System.out.println("buildDisplayScreen: 1080p 60hz 显示器");
    }

    @Override
    Computer getComputer() {return computer;}
}

测试一下:

public class Test {public static void main(String[] args) {
        // 创立低配置电脑建造者
        LowConfigurationComputerBuilder builder = new LowConfigurationComputerBuilder();
        builder.buildCpu();
        builder.buildGraphicsCard();
        builder.buildDisplayScreen();
        Computer computer = builder.getComputer();
        System.out.println("建造出的电脑:" + computer);
    }
}

执行后果:

buildCpu: 英特尔酷睿 i5 处理器
buildGraphicsCard: 8g 内存
buildDisplayScreen: 1080p 60hz 显示器
建造出的电脑: Computer{cpu=’ 英特尔酷睿 i5 处理器 ’, graphicsCard=’8g 内存 ’, displayScreen=’1080p 60hz 显示器 ’}

(三) 客户分割销售公司

尽管下面的办法是比第一种强一些,然而客户本人去分割生产技术人员,显然不是很正当,失常的做法,咱们都是先去分割销售公司,通知他们我想要什么配置的电脑就能够了,细节我并不想管

public class SalesCompany {public Computer buildComputer(ComputerBuilder builder){builder.buildCpu();
        builder.buildGraphicsCard();
        builder.buildDisplayScreen();
        return builder.getComputer();}
}

测试代码

public class Test {public static void main(String[] args) {
        // 创立低配置电脑建造者
        LowConfigurationComputerBuilder builder = new LowConfigurationComputerBuilder();
        // 创立电脑销售核心
        SalesCompany salesCompany = new SalesCompany();
        // 指定具体的电脑建造者去实现 电脑 这个产品
        Computer computer = salesCompany.buildComputer(builder);
        System.out.println("建造出的电脑:" + computer);
    }
}

当初代码曾经比较完善了,也就是咱们买家通过分割电脑销售核心,而后销售核心去调用用户想要的配置的建造者,方才咱们创立的是一个“低配置电脑建造者”,如果咱们想要换成中等配置的电脑,该怎么做呢?

当初只须要减少一个中等配置电脑建造者,实现 Builder 抽象类就能够了

/**
 * 低配置电脑
 */
public class MiddleConfigurationComputerBuilder extends ComputerBuilder {

    private Computer computer;

    public MiddleConfigurationComputerBuilder(){computer = new Computer();
    }

    @Override
    void buildCpu() {computer.setCpu("英特尔酷睿 i7 处理器");
        System.out.println("buildCpu: 英特尔酷睿 i7 处理器");
    }

    @Override
    void buildGraphicsCard() {computer.setGraphicsCard("16g 内存");
        System.out.println("buildGraphicsCard: 16g 内存");
    }

    @Override
    void buildDisplayScreen() {computer.setDisplayScreen("2k 144hz 显示器");
        System.out.println("buildDisplayScreen: 2k 60hz 显示器");
    }

    @Override
    Computer getComputer() {return computer;}
}

测试一下

public class Test {public static void main(String[] args) {MiddleConfigurationComputerBuilder builder = new MiddleConfigurationComputerBuilder();
        // 创立电脑销售核心
        SalesCompany salesCompany = new SalesCompany();
        // 指定具体的电脑建造者去实现 电脑 这个产品
        Computer computer = salesCompany.buildComputer(builder);
        System.out.println("建造出的电脑:" + computer);
    }
}

运行后果

buildCpu: 英特尔酷睿 i7 处理器
buildGraphicsCard: 16g 内存
buildDisplayScreen: 2k 60hz 显示器
建造出的电脑: Computer{cpu=’ 英特尔酷睿 i7 处理器 ’, graphicsCard=’16g 内存 ’, displayScreen=’2k 144hz 显示器 ’}

其实到这里一个建造者模式的实例就写完了,上面咱们联合概念,来深刻了解一下建造者模式

三 建造者模式

(一) 概念

建造者模式:将一个简单对象的构建与它的示意拆散,使得同样的构建过程能够创立不同的示意

  • 也就是说,产品的生成过程 或者说 组成 ,是 不变 的,而每一部分都是能够自行抉择的,即其 内部表象是能够变动 的,这也就是所说的变与不变相拆散
  • 此种状况下,用户只须要指定建造的类型就能够失去他们,而具体的过程和细节就不须要晓得了

(二) 优缺点

首先,此模式封装性好,构建和示意进行了拆散,每一个建造者都是互相独立的,利于解耦和扩大,合乎“开闭准则”同时客户调用时,不须要晓得产品细节

然而也正是因为产品生成过程这个不变的局部,限度了它的应用范畴,同时如果产品外部日后产生什么扭转,则建造者也得同样批改,保护老本不小

(三) 构造

依据下面的结构图,咱们别离阐明一下其中的四个角色(除 Client 调用者以外)

  • Product(产品角色):多个组件形成的简单对象,即上述例子中的电脑
  • Builder(形象建造者):一个蕴含创立产品各个子部件的形象办法的接口 / 抽象类,个别还蕴含一个返回后果的办法,如上述中的 ComputerBuilder 类
  • ConcreteBuilder(具体建造者):Builder 的具体实现类,如上述中具体的 低配置电脑建造者 和 中等配置电脑建造者
  • Director(指挥者):调用建造者对象中的部件结构与拆卸办法,以创立一个简单对象

    • 指挥者中不含具体产品信息
    • 其隔离了客户与对象的生产过程

(四) 实用场景

  • 程序会对同一办法的后果产生影响,例如建房子,该当先打地基,再架钢筋水泥
  • 同一个对象能够拆卸不同的部件或者整机,同时后果不同
  • 产品类有简单的内部结构,且这些产品对象具备共性
正文完
 0