生成器模式(建造者模式)
生成器模式是指将一个复杂对象的构建与它的表示分离,使同样的构建过程可以创建不同的表示。适合该模式的情况如下:对象结构复杂,利用构造方法创建对象无法满足用户需求;对象创建过程必须独立于创建该对象的类。
有些类是不宜直接创建对象的。成员变量是自定义类型:
public class Product{
Unit u;
Unit2 u2;
Unit3 u3;
}
Product 是由Unit;Unit2;Unit3组成,所以该对象的产生不能简单的new Product (Unit,Unit2,Unit3)组成。必须分别生成具体的u;u2;u3,然后才能获得Product对象。
实现如下:
public class Product {
Unit unit;
Unit2 unit2;
Unit3 unit3;
public void createUnit(){
unit = new Unit();
} // 创建具体单元1
public void createUnit2(){
unit2 = new Unit2();
} // 创建具体单元2
public void createUnit3(){
unit3 = new Unit3();
} // 创建具体单元3
public void composite(){ // 合成具体的Product 对象
// unit + unit2 + unit3
}
public static void main(String[] args) {
Product p = new Product();
p.createUnit();p.createUnit2();p.createUnit3();
p.composite();
}
}
随着Produt产品种类的增多或者减少,必须修改已有的源代码,这是我们不希望看到的情况。
设计思路
1.常规思路是在一个包含N种Produt产品的所有代码。
2.生成器思路是产品类与创建产品的类相分离,产品类仅1个,创建产品的类有n个。由此可以递进推出生成器模式编程:
定义一个产品类:
public class Unit { }
public class Unit2 { }
public class Unit3 { }
public class Product {
Unit unit;
Unit2 unit2;
Unit3 unit3;
}
定义n个生成器Build类
生成器用来生成Poduct对象,一般来说生成器是一个成员变量;需要创建三个unit对象并且通过composite装配在一个Produt对象中。
定义接口:
public interface IBuild {
public void createUnit();
public void createUnit2();
public void createUnit3();
public Product composite();
}
定义实现类:
实现类1
public class BuildProdut implements IBuild {
Product product = new Product();
@Override
public void createUnit() {
// 创建Unit
}
@Override
public void createUnit2() {
// 创建Unit2
}
@Override
public void createUnit3() {
// 创建Unit3
}
@Override
public Product composite() {
return product;
}
}
实现类2
public class BuildProdut2 implements IBuild {
Product product = new Product();
@Override
public void createUnit() {
// 创建Unit
}
@Override
public void createUnit2() {
// 创建Unit2
}
@Override
public void createUnit3() {
// 创建Unit3
}
@Override
public Product composite() {
return product;
}
}
通过上面代码可知:若需求分析发生变化,只需增加或删除相应的生成器类即可,无需修改已有的代码。
定义Director类
该类是对生成器接口IBuild的封装。
public class Director {
private IBuild iBuild;
public void setIBuild (IBuild iBuild){
this.iBuild = iBuild;
}
public Product getiBuild(){
iBuild.createUnit();
iBuild.createUnit2();
iBuild.createUnit3();
return iBuild.composite();
}
}
总结:通过分析上述代码,可知生成器设计模式涉及四个关键角色:产品(Product)、抽象生成器(IBuild)、具体生成器(Build)、指挥者(Director)。四者的UML关系如图:
深入理解生成器模式
1 深入理解调度类(指挥者)Director
理解Director类,必须先理解好IBuild。与常用接口相比,生成器接口IBuild是特殊的,它是一个流程控制接口,该接口中定义的方法必须依照某种顺序运行,一个都不能缺,因此,在程序中一定要体现“流程这一特点”。Director类既是对“流程”的封装类,其中的build()方法决定了具体的流程控制过程。
2.深入理解IBuild接口定义
IBuild接口清晰地反映了创建产品Product的流程。如果将UML类图改为下图:
public interface IBuild {
public Product create();
}
// 定义一个具体的生成器类
public class BuildProduct implements IBuild {
Product product = new Product();
public void createUnit() {
// 创建Unit
}
public void createUnit2() {
// 创建Unit2
}
public void createUnit3() {
// 创建Unit3
}
@Override
public Product create() {
createUnit();createUnit2();createUnit3();
return product;
}
}
// 定义指挥者类
public class Director {
private IBuild build;
public Director(IBuild build){
this.build = build;
}
public Product build(){
return build.create();
}
}
具体生成器多态create()方法中包含了创建Product对象的全过程,所以Director类中的build()方法就显得重复了,那么是否说明可以略去Director类呢?单纯就本题而言,是可以的。也就是说,在生成器模式中,抽象生成器和具体生成器是必须的,而指挥者类需要在实际问题中考虑。
本方法中利用多态create()方法可以解决更为复杂的问题。例如,要生产两种poduct产品:一种需要三个过程;一种需要四个过程。此时,若生成器模式如第一幅图就不行了,因为它要求创建产品的过程必须相同;用图二就可以,只需要在第一个具体生成器中定义四个普通方法,在第二个具体生成器中定义三个普通方法就行了。这种模式也可以叫弱生成器模式。
进一步思考:可以把IBuild定义成泛型接口,如下:所具体生成器皆可从此接口派生。
public interface IBuild<T> {
public T create();
}
派生类方法实现生成器模式
利用Product派生类方法,也可以实现类似的生成器功能。
// 定义抽象生成器:
public abstract class Product {
Unit unit;
Unit2 unit2;
Unit3 unit3;
abstract void createUnit(); // 创建
abstract void createUnit2();
abstract void createUnit3();
abstract void composite();
}
// 定义具体生成器
public class BuildProduct extends Product {
@Override
void createUnit() {
}
@Override
void createUnit2() {
}
@Override
void createUnit3() {
}
@Override
void composite() {
}
}
// 定义指挥者类
public class Director {
Product product;
public Director(Product product){
this.product = product;
}
void build(){
product.createUnit();
product.createUnit2();
product.createUnit3();
product.composite();
}
}