一、引子
前几天陪朋友去装机店攒了一台电脑,看着装机工在那里熟练的装配着机器,不禁想起来了培训时讲到的建造模式。作为装机工,他们不用管你用的CPU是Intel还是AMD,也不管你的显卡是2000千大元还是白送的,都能三下五除二的装配在一起——一台PC就诞生了!当然对于客户来说,你也不知道太多关于PC组装的细节。这和建造模式是多么的相像啊!
今天就来探讨一下建造模式
二、定义与结构
GOF给建造模式的定义为:将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。可以将建造模式的精髓概括为:将构造复杂对象的过程和对象的部件解耦。这是对降低耦合、提高可复用性精神的一种贯彻。其实这种精神贯彻在GOF几乎所有的设计模式中。
是不是和上面提到的装机流程相像?
这个很多人认为同抽象工厂模式相似的建造模式用在什么样的设计环境下呢(对于两者的比较稍候讨论)?我认为可以总结为以下环境:当要生成的产品有复杂的内部结构,其中的内部结构由多个对象组成;系统将来可能要改变产品对象的内部结构的构成或者实现方式,比如说产品的一些属性现在是从数据库中得到的,而将来可能从XML中解析得到;而且不能将产品的内部构造完全暴露给客户程序,一是为了可用性,二是为了安全等因素。满足上面的设计环境就可以考虑使用建造模式来搭建框架了。 来看看建造模式的组成吧。
抽象建造者角色:这个角色用来规范产品对象的各个组成成分的建造。一般而言,此角色独立于应用程序的商业逻辑。
具体建造者角色:担任这个角色的是于应用程序紧密相关的类,它们在指导者的调用下创建产品实例。这个角色在实现抽象建造者角色提供的方法的前提下,达到完成产品组装,提供成品的功能。
指导者角色:调用具体建造者角色以创建产品对象。指导者并没有产品类的具体知识,真正拥有产品类的具体知识的是具体建造者对象。 产品角色:建造中的复杂对象。它要包含那些定义组件的类,包括将这些组件装配成产品的接口。
来看下这些角色组成的类图:
<!--StartFragment -->
首先客户程序创建一个指导者对象,一个建造者角色,并将建造者角色传入指导者对象进行配置。然后,指导者按照步骤调用建造者的方法创建产品。最后客户程序从建造者或者指导者那里得到产品。
从建造模式的工作流程来看,建造模式将产品的组装“外部化”到了建造者角色中来。这是和任何正规的工厂模式不一样的——产品的创建是在产品类中完成的。
三、实现
实在找不到太好的例子,我认为《java与模式》中发邮件的例子还算可以。这里我将《Think in Patterns with Java》中的例子放到这里权且充个门面。媒体可以存在不同的表达形式,比如书籍、杂志和网络。这个例子表示不同形式的媒体构造的步骤是相似的,所以可以被提取到指导者角色中去。
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);
}
}
在实现的时候,抽象建造角色提供的接口必须足够普遍,以适应不同的具体建造角色。对于一个建造角色来说可能某个步骤是不需要的,可以将此接口实现为空。多个产品之间可能没有太多的共同点,可以提供一个标示接口作为抽象产品角色;也可以不提供抽象产品角色,这时要将提供产品的接口从抽象建造角色里面去掉,不然就会编译出问题。
四、应用优点
建造模式可以使得产品内部的表象独立变化。在原来的工厂方法模式中,产品内部的表象是由产品自身来决定的;而在建造模式中则是“外部化”为由建造者来负责。这样定义一个新的具体建造者角色就可以改变产品的内部表象,符合“开闭原则”。
建造模式使得客户不需要知道太多产品内部的细节。它将复杂对象的组建和表示方式封装在一个具体的建造角色中,而且由指导者来协调建造者角色来得到具体的产品实例。
每一个具体建造者角色是毫无关系的。
建造模式可以对复杂产品的创建进行更加精细的控制。产品的组成是由指导者角色调用具体建造者角色来逐步完成的,所以比起其它创建型模式能更好的反映产品的构造过程。
五、扩展
建造模式中很可能要用到组成成品的各种组件类,对于这些类的创建可以考虑使用工厂方法或者原型模式来实现,在必要的时候也可以加上单例模式来控制类实例的产生。但是要坚持一个大前提就是要使引入的模式给你的系统带来好处,而不是臃肿的结构。 建造模式在得到复杂产品的时候可能要引用多个不同的组件,在这一点上来看,建造模式和抽象工厂模式是相似
- 大小: 35.3 KB
分享到:
相关推荐
大数据这一概念代表了信息和通信技术的最新发展趋势,其核心是通过分析和处理海量数据来揭示其中的模式、趋势和关联性,进而实现对未来事件的预测。大数据的应用能够帮助行业进行精准的市场定位、风险控制、成本优化...
在《设计模式浅谈24种》中,主要讨论了24种经典的GOF设计模式,这些模式被分为三大类:创建型、结构型和行为型。 创建型模式主要关注对象的创建,包括以下几个核心模式: 1. **Abstract Factory**(抽象工厂)模式...
总之,智能建造在工程管理中的实践应用不仅提升了建筑业的生产效率,也带来了新的管理理念和模式。面对挑战,建筑单位需要在引进新技术的同时,注重成本控制和规划合理性,以实现智能建造的全面落地,推动行业的高...
若公司自行或通过母公司建设,按建造合同确认收入;若工程承包给第三方,则不确认收入,仅按结算对价确认资产。 2. **资产的确认**:资产确认分为金融资产模式、无形资产模式和混合模式。 - 金融资产模式:当授予...
- 建造者模式:将一个复杂对象的构建与其表示分离,使同样的构建过程可以创建不同的表示。 - 构造器模式(原型模式):通过复制已有对象来创建新对象。 2. 结构型设计模式: - 适配器模式:将两个不兼容的接口...
5. **协同工作与持续改进**:IPD强调团队协作,结合精益建造理论,通过各阶段的优化,确保项目在每个层次都能达到最佳状态。 6. **提高工程质量和效率**:通过集成化的管理,IPD模式能够减少错误和返工,提升工程...
1. **创建型模式**:如工厂方法(Factory Method)、抽象工厂(Abstract Factory)、单例(Singleton)、建造者(Builder)和原型(Prototype)。这些模式关注于对象的创建过程,旨在提供灵活的实例化机制。 2. **...
本篇将深入探讨12种核心的设计模式,它们是:单例模式、工厂模式、抽象工厂模式、建造者模式、原型模式、适配器模式、装饰器模式、代理模式、桥接模式、组合模式、享元模式和观察者模式。 1. **单例模式**:确保一...
例如,代理型管理模式侧重于机场运营的代理和咨询服务,风险型管理模式强调风险分担和控制,设计建造模式(Design-Build)则将设计和建造任务交由同一承包商,这样可以在很大程度上简化流程并缩短工期。BOT模式...
### 浅谈框架与MVC #### 架构的重要性及概念 在软件开发领域,架构设计扮演着至关重要的角色。良好的架构设计不仅能够确保软件系统的稳定性、可维护性和可扩展性,还能提升团队协作效率。正如文章所述,“好的产品...
建造者模式将复杂对象的构建与其表示分离,使得同样的构建过程可以创建不同的表示。它适用于需要构建多个部分的对象,且各部分构造顺序可能变化的情况。在C#中,通常会定义一个建造者类和一个指导构造过程的导演类...
《漫谈设计模式》这本书深入浅出地介绍了多种设计模式,通过代码实例帮助读者理解和应用这些模式。在这个压缩包“ramblingonpatterns-1.0”中,你将找到书中的代码示例,它们覆盖了各个章节的关键知识点。 1. **...
同样地,在软件开发领域中,诸如领域驱动设计(DDD)、模型视图控制器(MVC)等模式也被视为特定领域的架构设计。 ### 三、架构的本质 架构的概念最初源自建筑行业,指代建筑物的设计和构造过程。将这一概念应用于...
在建筑领域,3D打印可以快速建造房屋,缩短工期,降低人工成本;在航空航天领域,轻量化、复杂结构的零件可以通过3D打印高效生产;在教育中,3D打印为学生提供了一种直观学习物理模型的方式,激发创新思维。 然而,...
"浅谈电动汽车充电站的发展运营与造价成本控制" 本文主要讨论了电动汽车充电站的发展运营和造价成本控制。文章指出,国家出台了一系列优惠政策推广新能源电动汽车,但是充电基础设施建设滞后一直是制约电动汽车发展...
【文章标题】:“浅谈特大型城市道路工程基于BIM全生命周期协同管理平台架构研究” 【文章摘要】:本文以北横通道工程建设为例,探讨了如何利用BIM(建筑信息模型)技术和GIS(地理信息系统)建立全生命周期协同...
【标题】: "浅谈中学数学教学中如何培养学生的创新能力" 【描述】: 本文探讨了在中学数学教育中如何激发和培养学生的创新能力,强调了创新教育在素质教育中的重要地位,尤其是在逻辑性强的数学学科中。文章通过实例...
这种问题不仅在理论计算机科学中占有重要地位,而且在实际应用中也有广泛的应用场景,例如在图像处理领域用于识别图像中的特定区域,或者在数据分析中用于发现数据集中的异常模式。 #### 二、基本概念 - **有效...