上一篇:设计模式(四)——原型模式
下一篇:设计模式(六)——适配器模式
一、概要
官方解释: 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类复杂化。使用建造者模式,将一种具体建造者对应一种车型,符合单一职责原则。
三、小结
建造者模式适用于多个组件构成的产品的新建,可以按照自己的意愿使用组件组成产品并查看产品组件。学习建造者模式有利于加强面向对象的理解,数量掌握建造者模式可以使软件开发事半功倍。
上一篇:设计模式(四)——原型模式
下一篇:设计模式(六)——适配器模式