建造者模式

1.建造者模式是什么

1.百度百科

建造者模式是设计模式的一种,将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。

2.维基百科

The builder pattern is an object creation software design pattern. Unlike the abstract factory pattern and the factory method pattern whose intention is to enable polymorphism, the intention of the builder pattern is to find a solution to the telescoping constructor anti-pattern[citation needed] that occurs when the increase of object constructor parameter combination leads to an exponential list of constructors. Instead of using numerous constructors, the builder pattern uses another object, a builder, that receives each initialization parameter step by step and then returns the resulting constructed object at once.

The builder pattern has another benefit: It can be used for objects that contain flat data (HTML code, SQL query, X.509 certificate…), that is to say, data that can't be easily edited step by step and hence must be edited at once.[citation needed]

Builder often builds a Composite. Often, designs start out using Factory Method (less complicated, more customizable, subclasses proliferate) and evolve toward Abstract Factory, Prototype, or Builder (more flexible, more complex) as the designer discovers where more flexibility is needed. Sometimes creational patterns are complementary: Builder can use one of the other patterns to implement which components are built. Builders are good candidates for a fluent interface.

3.lz理解

将复杂的创建过程从客户端抽取出来,形成一个建造角色,建造角色来创建对象完成复杂对象的构建。客户端只需依赖建造角色,而不必依赖各个具体的部件对象。

什么是复杂对象:是指那些包含多个成员属性的对象,这些成员属性也称为部件或零件,如程序猿要会识字、会数学、会编程语言,会设计模式等等。

4.核心角色

抽象建造角色(builder) 为一个产品各个部件指定抽象接口。在该接口中一般声明两类方法,一类方法是buildXXX(),它们用于创建复杂对象的各个部件;另一类方法是getXXX(),它们用于返回复杂对象。Builder并不负责具体的创建过程,由具体的子类完成。Builder既可以是抽象类,也可以是接口。

具体建造角色(ConcreteBuilder) 它实现了Builder接口,实现各个部件的具体构造和装配方法,定义并明确它所创建的复杂对象,也可以提供一个方法返回创建好的复杂产品对象。返回一个创建好的对象。

产品角色(Product) 它是被构建的复杂对象,包含多个组成部件,具体建造者ConcreteBuilder创建该产品的内部表示并定义它的装配过程。也就是我们最终要得到的复杂对象。

指挥角色(Director) 指挥者又称为导演类,它负责安排复杂对象的建造次序,指挥角色(Director)与抽象建造角色(builder)之间存在关联关系,可以在其建造方法中调用具体建造角色(ConcreteBuilder)的部件构造与装配方法,完成复杂对象的建造。客户端一般只需要与指挥角色(Director)进行交互,在客户端确定具体建造者的类型,并实例化具体建造角色对象(ConcreteBuilder),然后通过指挥类(Director)的构造函数或者Setter方法将该对象传入指挥类(Director)中。也就是用来控制创建流程。

在现实开发中,往往省去Director的角色,而直接使用一个具体建造角色(ConcreteBuilder)来进行对象的组装。

2.建造者模式解决了什么问题

解除耦合 将复杂产品的创建步骤分解在不同的方法中,使得创建过程更加清晰,使得我们能够更加精确的控制复杂对象的产生过程。

高度封装 将产品的创建过程与产品本身分离开来,可以使用相同的创建过程来得到不同的产品。也就说细节依赖抽象。

自由拓展 每一个具体建造者都相对独立,而与其他的具体建造者无关,因此可以很方便地替换具体建造者或增加新的具体建造者,用户使用不同的具体建造者即可得到不同的产品对象。

3.建造者模式用法

我们就拿造车来举例子。想造一个汽车,需要各种部件。比如轮子、车体、发动机、变速器等。这里我们就从简2个部件一个车体一个变速器,现在我们要建造两种车型自动档变速器、手动档变速器。

车体、变速器。产品部件

/**
 * 抽象车体
 */
public interface CarBody {

}
/**
  * 具体车体
  */
public class RuggedCarBody implements CarBody {

	public RuggedCarBody() {
		System.out.print("坚固车体建造完毕");
	}

}

/**
 * 抽象变速器
 */
public interface Transmission {

	void changeSpeed();

}
//具体变速器

/**
 * 手动变速器
 */
public class ManaulTransmission implements Transmission {

	public ManaulTransmission() {
		System.out.print("手动变速器建造完成");
	}

	@Override
	public void changeSpeed() {
		System.out.print("手动变速");
	}

}

/**
 * 自动变速器
 */
public class AutomaticTransmission implements Transmission {

	public AutomaticTransmission() {
		System.out.print("自动变速器建造完成");
	}

	@Override
	public void changeSpeed() {
		System.out.print("自动变速");
	}

}

汽车 产品角色

/**
 * 汽车 产品角色
 */
public class Car {

	private CarBody carBody;

	private Transmission transmission;

	// private AutomotiveTransmission automotiveTransmission;

	public CarBody getCarBody() {
		return carBody;
	}

	public void setCarBody(CarBody carBody) {
		this.carBody = carBody;
	}

	public Transmission getTransmission() {
		return transmission;
	}

	public void setTransmission(Transmission transmission) {
		this.transmission = transmission;
	}

}

抽象建造者、具体建造者

/**
 * 汽车制造 抽象建造角色
 */
public interface Builder {

	void buildCarBody(CarBody carBody);

	void buildTransmission(Transmission transmission);

	Car getCar();

}

/**
 * 具体建造者
 */
public class CarBulider implements Builder {

	private Car car = new Car();

	@Override
	public void buildCarBody(CarBody carBody) {
		car.setCarBody(carBody);
	}

	@Override
	public void buildTransmission(Transmission transmission) {
		car.setTransmission(transmission);

	}

	@Override
	public Car getCar() {
		return car;
	}

}

指挥角色

public class Director {

	private Builder builder = new CarBulider();

	public Car getAutomaticCar() {
		System.out.println();
		builder.buildCarBody(new  RuggedCarBody());
		builder.buildTransmission(new AutomaticTransmission());
		System.out.print("自动档汽车建造完毕");
		return builder.getCar();
	}

	public Car getManaul() {
		System.out.println();
		builder.buildCarBody(new  RuggedCarBody());
		builder.buildTransmission(new ManaulTransmission());
		System.out.print("手动档汽车建造完毕");
		return builder.getCar();
	}

}

客户端调用

public class Customer {

	public static void main(String[] args) {
		Director director = new Director();
		director.getAutomaticCar();
		director.getManaul();
	}

}

结果

坚固车体建造完毕
自动变速器建造完成
自动档汽车建造完毕

坚固车体建造完毕
手动变速器建造完成
手动档汽车建造完毕

4.建造者模式的问题

灵活性不足 建造者模式所创建的产品一般具有较多的共同点,其组成部分相似,如果产品之间的差异性很大,则不适合使用建造者模式,因此其使用范围受到一定的限制。
建造类膨胀 如果产品的内部变化复杂,可能会导致需要定义很多具体建造者类来实现这种变化,导致系统变得很庞大。

5.建造者模式总结

使用场景:

  1. 创建的产品包含比较多的成员属性(部件)。
  2. 创建多个不同产品,产品具有较多的类型相同部件。
  3. 需要控制产品创建流程。

一般我们在创建一个对象时采用的一般方法有2种,一个是多参数的构造方法、另一个是使用set方法将对象的属性设置进去。但是当一个对象中拥有数量较多的属性时使用set方法和使用多参构造都会使代码编的难以理解,并且使用起来需要new一大堆成员对象场面十分混乱。并且set方式还容易漏掉部分对象。而且构造方法创建过程必须放在构造方法中,set方法构造过程必须在者客户端中。构造流程和业务流程全部混合在一起,一但构造方式或者构造的成员有所变化需要修改多处代码,难免出现bug。而建造者模式封装了构建流程,客户端只需向指挥角色去"要"一个对象即可,其构建过程封装,对象获取简单。这简直是屠龙宝刀、点击就送啊 😛

引用

http://blog.csdn.net/yanbober/article/details/45338041

posted @ 2018-02-05 15:04  枫飘雪落  阅读(259)  评论(0编辑  收藏  举报