设计模式(五)——建造者模式

mac2022-06-30  23

上一篇:设计模式(四)——原型模式

下一篇:设计模式(六)——适配器模式

一、概要

官方解释:Separate the construction of a complex object form its representation so that the same construction process can create different representations.(将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。)我的理解:

       建造者模式包含的角色:指挥者类、建造者类(根据需要可以有一个抽象建造者、多个具体建造者或者仅一个具体建造者)、产品类和组成产品使用的组件类

       核心类是建造者类,产品类引用注入到建造者类中,建造者类引用注入到指挥者类中,所以建造者类是产品类和指挥者类的桥梁,与客户端沟通的是指挥者类。

 工厂模式建造者模式抽象化(面向接口)产品(一个抽象产品类/接口+多个具体产品类)建造者(一个建造者类/接口+多个具体建造者)新建产品

在工厂方法中,根据参数新建具体产品对象并返回

在具体建造者类中,组装零件构建产品

根本区别产品的不同直接源于具体产品类不同,即一个具体产品类对于一种产品产品类Product是公用的,产品的不同源于具体建造者的不同,一个具体builder对于一种产品

参与者:建造者(AbstractBuilder抽象建造者、ConcreteBuilder具体建造者)、产品类Product、指挥者类Director

类图:

partA、partB、partC可以不使用String,使用自定义类,和下面的代码那样,没有关系,这并不是建造者模式关注的重点。

(这里使用partA、partB、partC为String类型使类图简化,不涉及建造者模式的部分去掉,有利于读者理解)

二、代码

        汽车分为轿车和suv,两种车型都由三大件组成(发动机、变速箱、底盘),但是两种车型的具体三大件不同,构建轿车使用的是轿车建造者(CarBuilder),构建SUV使用的是SUV构建者(SuvBuilder)。其中Car类是一样的,仅因为构建者不同而产生不同的车型,最后在客户端构建并打印具体三大件。

public class TestBuilderPattern { public static void main(String[] args) { Director director = new Director(); director.setBuilder(new CarBuilder()); director.build(); director.display(); System.out.println("==========================="); director.setBuilder(new SuvBuilder()); director.build(); director.display(); } } class Director { private AbstractCarBuilder builder; public void build() { builder.buildBasePlate(); builder.buildGearBox(); builder.buildEngine(); } public AbstractCarBuilder getBuilder() { return builder; } public void setBuilder(AbstractCarBuilder builder) { this.builder = builder; } public void display() { System.out.println("发动机: " + builder.getCar().get_eEngine()); System.out.println("底盘: " + builder.getCar().get_bBasePlate()); System.out.println("变速箱: " + builder.getCar().get_gGearBox()); } } interface Engine { } interface BasePlate { } interface GearBox { } class CarEngine implements Engine { } class CarBasePlate implements BasePlate { } class CarGearBox implements GearBox { } class SUVEngine implements Engine { } class SUVBasePlate implements BasePlate { } class SUVGearBox implements GearBox { } abstract class AbstractCarBuilder { protected Car car = new Car(); public Car getCar() { return car; } public void setCar(Car car) { this.car = car; } abstract void buildEngine(); abstract void buildBasePlate(); abstract void buildGearBox(); } class CarBuilder extends AbstractCarBuilder { @Override public void buildEngine() { car.set_eEngine(new CarEngine()); } @Override public void buildBasePlate() { car.set_bBasePlate(new CarBasePlate()); } @Override public void buildGearBox() { car.set_gGearBox(new CarGearBox()); } } class SuvBuilder extends AbstractCarBuilder { @Override public void buildEngine() { car.set_eEngine(new SUVEngine()); } @Override public void buildBasePlate() { car.set_bBasePlate(new SUVBasePlate()); } @Override public void buildGearBox() { car.set_gGearBox(new SUVGearBox()); } } class Car { private Engine _eEngine; private BasePlate _bBasePlate; private GearBox _gGearBox; public Engine get_eEngine() { return _eEngine; } public void set_eEngine(Engine _eEngine) { this._eEngine = _eEngine; } public BasePlate get_bBasePlate() { return _bBasePlate; } public void set_bBasePlate(BasePlate _bBasePlate) { this._bBasePlate = _bBasePlate; } public GearBox get_gGearBox() { return _gGearBox; } public void set_gGearBox(GearBox _gGearBox) { this._gGearBox = _gGearBox; } }

输出:

发动机: mypackage.CarEngine@15db9742 底盘: mypackage.CarBasePlate@6d06d69c 变速箱: mypackage.CarGearBox@7852e922 发动机: mypackage.SUVEngine@4e25154f 底盘: mypackage.SUVBasePlate@70dea4e 变速箱: mypackage.SUVGearBox@5c647e05

问题:与不使用建造者模式相对比,体现建造者模式的优势?

不使用建造者——去掉Builder

public class TestBuilderPattern { public static void main(String[] args) { Director director = new Director(); director.buildCar(); director.display(); director.buildSUV(); director.display(); } } class Director { private Car car = new Car(); public void buildCar() { car.set_bBasePlate(new CarBasePlate()); car.set_gGearBox(new CarGearBox()); car.set_eEngine(new CarEngine()); } public void buildSUV() { car.set_bBasePlate(new SUVBasePlate()); car.set_eEngine(new SUVEngine()); car.set_gGearBox(new SUVGearBox()); } public void display() { System.out.println("发动机: " + car.get_eEngine()); System.out.println("底盘: " + car.get_bBasePlate()); System.out.println("变速箱: " + car.get_gGearBox()); } } interface Engine { } interface BasePlate { } interface GearBox { } class CarEngine implements Engine { } class CarBasePlate implements BasePlate { } class CarGearBox implements GearBox { } class SUVEngine implements Engine { } class SUVBasePlate implements BasePlate { } class SUVGearBox implements GearBox { } class Car { private Engine _eEngine; private BasePlate _bBasePlate; private GearBox _gGearBox; public Engine get_eEngine() { return _eEngine; } public void set_eEngine(Engine _eEngine) { this._eEngine = _eEngine; } public BasePlate get_bBasePlate() { return _bBasePlate; } public void set_bBasePlate(BasePlate _bBasePlate) { this._bBasePlate = _bBasePlate; } public GearBox get_gGearBox() { return _gGearBox; } public void set_gGearBox(GearBox _gGearBox) { this._gGearBox = _gGearBox; } }

输出:

发动机: mypackage.CarEngine@15db9742 底盘: mypackage.CarBasePlate@6d06d69c 变速箱: mypackage.CarGearBox@7852e922 发动机: mypackage.SUVEngine@4e25154f 底盘: mypackage.SUVBasePlate@70dea4e 变速箱: mypackage.SUVGearBox@5c647e05

小结:去掉Builder后,具体建造方法放到了Director类中,若有n个具体车型,则Director类中需提供n中build()方法,Director类复杂化。使用建造者模式,将一种具体建造者对应一种车型,符合单一职责原则。 

三、小结

      建造者模式适用于多个组件构成的产品的新建,可以按照自己的意愿使用组件组成产品并查看产品组件。学习建造者模式有利于加强面向对象的理解,数量掌握建造者模式可以使软件开发事半功倍。

 

上一篇:设计模式(四)——原型模式

下一篇:设计模式(六)——适配器模式

最新回复(0)