建造者模式(Builder Pattern)也叫生成器模式,起定义:Seperate the construction of a complex object from its representation so that the same construction process can create different representations.(将一个复杂的对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示)。
其中setPart方法是零件的配置,什么是零件?其他的对象,获得一个不同的对象,或者不同的配置顺序就可能产生不同的产品。
需要注意的是,如果有多个产品类就有几个具体的建造者,而且这多个产品类具有相同接口或抽象类。
我们还需要一个导演来帮我们安排事情啦。
1)封装性。使用建造者模式可以使客户端不必需要产品内部组成的细节,如通用代码中我们不就不需要关心每一个具体的产品内部是如何实现的,产生的对象就是Product。
2)建造者独立,容易扩展。ConcreteBuilderA和ConcreteBuilderB是相互独立的,对系统的扩展非常有利。
3)便于控制细节风险。由于具体的建造者是独立,因此可以对建造过程中逐步细化,而不对其他的模块产生任何影响。
建造者模式的注意事项
建造者模式关注的是零件类型和装配工艺(顺序),这是它与工厂方法模式最大的不同地方,虽然同为创建类模式,但是注重点不同。
建造者模式的使用场景
1)相同的方法,不同的执行顺序,产生不同的事件结果时,可以采用建造者模式。
2)多个部件或者零件,都可以装配到一个对象中,但是产品的运行效果又不相同时,可以采用该模式。
3)产品类非常复杂,或者产品类中的调用顺序不同产生了不同效能,这个时候使用建造者模式非常适合。
4)在对象创建过程中会使用到系统中的一些其他对象,这些对象在产品对象的创建过程中不易得到时,也可以采用建造者模式封装该对象的创建过程。该场景只能是一个补偿方法,因为一个对象不容易获得,而在设计阶段竟然没有发现,而要通过建造者模式柔化创建过程,本身已经违反了设计的最初目标。
下面是建造者模式的通用代码,先看Product类,通常它是一个组合或继承产生的类。
//抽象产品类
public abstract class Product {
protected abstract void doSomething();
protected abstract void doAnything();
public void startAction() {
this.doSomething();
this.doAnything();
}
}
//具体产品类A
public class ConcreteProductA extends Product {
@Override
protected void doSomething() {
//业务处理
}
@Override
protected void doAnything() {
//业务处理
}
}
//具体产品类B
public class ConcreteProductB extends Product {
@Override
protected void doSomething() {
//业务处理
}
@Override
protected void doAnything() {
//业务处理
}
}
//抽象建造者
public abstract class Builder {
//设置产品的不同部分,以获得不同的产品
public abstract void setPart();
//建造产品
public abstract Product buildProduct();
}
其中setPart方法是零件的配置,什么是零件?其他的对象,获得一个不同的对象,或者不同的配置顺序就可能产生不同的产品。
//具体的建造者A
public class ConcreteBuilderA extends Builder {
private Product product = new ConcreteProductA();
//设置产品零件
public void setPart() {
//产品内的逻辑处理
}
public Product buildProduct() {
return product;
}
}
//具体的建造者B
public class ConcreteBuilderB extends Builder {
private Product product = new ConcreteProductB();
//设置产品零件
public void setPart() {
//产品内的逻辑处理
}
public Product buildProduct() {
return product;
}
}
需要注意的是,如果有多个产品类就有几个具体的建造者,而且这多个产品类具有相同接口或抽象类。
我们还需要一个导演来帮我们安排事情啦。
//导演类
public class Director {
private Builder builderA = new ConcreteBuilderA();
private Builder builderB = new ConcreteBuilderB();
//构建A产品
public Product getAProduct() {
builderA.setPart();
/*
*
*设置不同的零件,产生不同的产品
*/
return builderA.builderProduct();
}
//构建B产品
public Product getBProduct() {
builderB.setPart();
/*
*
*设置不同的零件,产生不同的产品
*/
return builderB.builderProduct();
}
}
//场景类
public class Client {
public static void main(String[] args) {
Director director = new Director();
//生产1万种产品A
for (int i = 0l i < 10000; ++i) {
director.getAProduct().startAction();
}
//生产1万种产品B
for (int i = 0l i < 10000; ++i) {
director.getBProduct().startAction();
}
}
建造者模式的优点
1)封装性。使用建造者模式可以使客户端不必需要产品内部组成的细节,如通用代码中我们不就不需要关心每一个具体的产品内部是如何实现的,产生的对象就是Product。
2)建造者独立,容易扩展。ConcreteBuilderA和ConcreteBuilderB是相互独立的,对系统的扩展非常有利。
3)便于控制细节风险。由于具体的建造者是独立,因此可以对建造过程中逐步细化,而不对其他的模块产生任何影响。
建造者模式的注意事项
建造者模式关注的是零件类型和装配工艺(顺序),这是它与工厂方法模式最大的不同地方,虽然同为创建类模式,但是注重点不同。