1.定义
—->GOF给建造模式的定义为:将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。这句话说得很抽象,不好理解,其实它的意思可以理解为:将构造复杂对象的过程和组成对象的部件解耦。就像攒电脑一样,不管什么品牌的配件,只要兼容就可以装上;同样,一样的配件,可以有好多组装的方式。这是对降低耦合、提高可复用性精神的一种贯彻。当要生成的产品有复杂的内部结构——比如由多个对象组成;而系统中对此产品的需求将来可能要改变产品对象的内部结构的构成,比如说产品的一些属性现在由一个小对象组成,而更改后的型号可能需要N个小对象组成;而且不能将产品的内部构造完全暴露给客户程序,一是为了可用性,二是为了安全等因素。满足上面的设计环境就可以考虑使用建造模式来搭建框架了。
2.组成
1)抽象建造者角色:这个角色用来规范产品对象的各个组成成分的建造。一般而言,此角色独立于应用程序的业务逻辑。
2)具体建造者角色:担任这个角色的是于应用程序紧密相关的类,它们在指导者的调用下创建产品实例。这个角色在实现抽象建造者角色提供的方法的前提下,达到完成产品组装,提供成品的功能。
3)指导者角色:调用具体建造者角色以创建产品对象。指导者并没有产品类的具体知识,真正拥有产品类的具体知识的是具体建造者对象。
4)产品角色:建造中的复杂对象。它要包含那些定义组件的类,包括将这些组件装配成产品的接口。
3.实现
import java.util.*;
import junit.framework.*;
//不同的媒体形式:
class Media extends ArrayList {}
class Book extends Media {}
class Magazine extends Media {}
class WebSite extends Media {}
// 进而包含不同的媒体组成元素:
class MediaItem {
private String s;
public MediaItem(String s) { this.s = s; }
public String toString() { return s; }
}
class Chapter extends MediaItem {
public Chapter(String s) { super(s); }
}
class Article extends MediaItem {
public Article(String s) { super(s); }
}
class WebItem extends MediaItem {
public WebItem(String s) { super(s); }
}
// 抽象建造者角色,它规范了所有媒体建造的步骤:
class MediaBuilder {
public void buildBase() {}
public void addMediaItem(MediaItem item) {}
public Media getFinishedMedia() { return null; }
}
//具体建造者角色
class BookBuilder extends MediaBuilder {
private Book b;
public void buildBase() {
System.out.println("Building book framework");
b = new Book();
}
public void addMediaItem(MediaItem chapter) {
System.out.println("Adding chapter " + chapter);
b.add(chapter);
}
public Media getFinishedMedia() { return b; }
}
class MagazineBuilder extends MediaBuilder {
private Magazine m;
public void buildBase() {
System.out.println("Building magazine framework");
m = new Magazine();
}
public void addMediaItem(MediaItem article) {
System.out.println("Adding article " + article);
m.add(article);
}
public Media getFinishedMedia() { return m; }
}
class WebSiteBuilder extends MediaBuilder {
private WebSite w;
public void buildBase() {
System.out.println("Building web site framework");
w = new WebSite();
}
public void addMediaItem(MediaItem webItem) {
System.out.println("Adding web item " + webItem);
w.add(webItem);
}
public Media getFinishedMedia() { return w; }
}
//指导者角色,也叫上下文
class MediaDirector {
private MediaBuilder mb;
public MediaDirector(MediaBuilder mb) {
this.mb = mb; //具有策略模式相似特征的
}
public Media produceMedia(List input) {
mb.buildBase();
for(Iterator it = input.iterator(); it.hasNext();)
mb.addMediaItem((MediaItem)it.next());
return mb.getFinishedMedia();
}
}
//测试程序——客户程序角色
public class BuildMedia extends TestCase {
private List input = Arrays.asList(new MediaItem[] {
new MediaItem("item1"), new MediaItem("item2"),
new MediaItem("item3"), new MediaItem("item4"),
});
public void testBook() {
MediaDirector buildBook = new MediaDirector(new BookBuilder());
Media book = buildBook.produceMedia(input);
String result = "book: " + book;
System.out.println(result);
assertEquals(result, "book: [item1, item2, item3, item4]");
}
public void testMagazine() {
MediaDirector buildMagazine = new MediaDirector(new MagazineBuilder());
Media magazine = buildMagazine.produceMedia(input);
String result = "magazine: " + magazine;
System.out.println(result);
assertEquals(result, "magazine: [item1, item2, item3, item4]");
}
public void testWebSite() {
MediaDirector buildWebSite = new MediaDirector(new WebSiteBuilder());
Media webSite = buildWebSite.produceMedia(input);
String result = "web site: " + webSite;
System.out.println(result);
assertEquals(result, "web site: [item1, item2, item3, item4]");
}
public static void main(String[] args) {
junit.textui.TestRunner.run(BuildMedia.class);
}
}