Java与模式5:builder(生成器)模式

Java与模式5:builder(生成器)模式

builder(生成器)模式:将一个产品的内部表象与产品的生成过程分割开来,从而可以使一个建造过程生成具有不同的内部表象的产品对象。

生成器模式的一个示例性类图:

builder模式示例类图
builder模式示例类图

如上图说示意的一样,生成器模式包括4个角色:

抽象建造者(builder)角色:给出一个抽象接口(类),以规范产品对象的各个组成成分的建造。一般而言,此接口独立于应用程序的商业逻辑。模式中直接创建产品对象的是具体建造者角色(concretebuilder)角色。具体建造者类必须实现这个接口所要求的两种方法:一种是建造方法,比如buildpart1()和buildpart2();另一种是结果返还方法,即本例子中的retrieveResult()。一般来说,产品所包含的零件数目与建造方法的数目相符。换言之,有多少零件,就有多少相应的建造方法。

具体建造者(concrete builder)角色:担任这个角色的是与应用程序逻辑紧密相关的类,他们在应用程序的调用下创建产品的实例。角色要完成的任务包括:

1)实现抽象建造者builder所声明的接口,给出一步一步地完成创建产品实例的操作。

2)在建造过程完成后,提供产品的实例

导演者(Director)角色:担任这个角色的类调用具体建造者角色以及创建产品对象。应当指出的是,导演者并没有产品类的具体知识,真正拥有产品具体知识的是具体建造者角色。

产品角色(Product):建造中国的负责对象,一个系统中会有多个产品类,而且这些产品类并不一定有共同的接口,而且完全可以不是向关联的。(这个时候可以使用标识接口)

上例中director代码(其他根据类图很容易)如下:

[code lang=”java”]
public class Director {
Builder builder;
public Director(Builder builder) {
this.builder = builder;
}

public void construct() {
builder.buildPart1();
builder.buildPart2();
builder.retrieveResult();
}

}

[/code]

客户端在调用的时候可以这么写:

[code lang=”java”]

public class Client {

public static void main(String[] args) {

Director director = new Director(new ConcreteBuilder1());

director.construct();

}

}

[/code]

注:

1)如果多个产品的零件的组成步骤相同的话,在builder抽象方法中可以在retriveResult()方法中进行统一的组织过程,即对通用组织过程的抽象,并非一成不变的在builder中不牵涉一点业务逻辑

2)在实际应用中如果具体建造者只有一个的情况下,Director的角色是可以省略的。同样建造者和具体建造者可以合并为一个类。其结构类图如:

无导演者角色的类图
无导演者角色的类图

思考:在什么情况下使用生成器模式呢?

1)需要生成的产品对象有复杂的内部结构。每一个内部成分本身可以是对象,也可以仅仅是一个对象(即产品对象)的一个组成部分

2)需要生成的产品对象的属性相互依赖。建造模式可以强制实行一种分步骤进行的建造过程,因此,如果产品对象的一个属性必须在另一个属性被赋值之后才可以赋值,使用建造模式比较适合。

3)在对象的创建过程中使用到系统中的其他一些对象,这些对象在产品对象的创建过程中不易得到。

使用建造模式主要有以下效果:

a.建造模式的使用使得产品的内部表现可以独立的变化,使用建造模式可以使得客户端不必知道产品内部细节。

b.每个builder都是相对独立的,

c.建造的产品更易于控制。

这个模式在结构上和抽象工厂模式很是相像。但是其实是不同的,其原因在于,抽象工厂模式中,每一个工厂对象被调用的时候都会返回一个完整的产品对象,而客户端可能会决定把这些产品组成一个更复杂的产品。建造类是一点一点造成一个复杂的产品,而这个产品的组装过程就发生在建造者角色内部。建造者模式的客户端拿到的是一个完整的最后产品。

在实际应用中就可以将上述模式进行结合使用,在建造类中就可以使用工厂模式的设计,返回一个完整的零件。

设计模式学习列表:Java设计模式学习笔记

张贴在未分类

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注