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

165 阅读4分钟

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

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

一、概要

官方解释: 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类复杂化。使用建造者模式,将一种具体建造者对应一种车型,符合单一职责原则。 

三、小结

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

 

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

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