参考文章
http://blog.youkuaiyun.com/hello_haozi/article/details/38819935
http://www.cnblogs.com/java-my-life/archive/2012/04/07/2433939.html
建造者模式
定义
将一个复杂对象的构造与它的表示分离,使同样的构建过程可以创建不同的表示,这样的设计模式被称为建造者模式(太抽象了,朕表示不能理解啊,啊,啊)产品的内部表象
一个产品常有不同的组成成分作为产品的零件,这些零件有可能是对象,也有可能不是对象,它们通常又叫做产品的内部表象(internal representation)。不同的产品可以有不同的内部表象,也就是不同的零件。使用建造模式可以使客户端不需要知道所生成的产品有哪些零件,每个产品的对应零件彼此有何不同,是怎么建造出来的,以及怎么组成产品。
先来看看这个UML图
创建一个产品类,产品类有两个零件part1和part2
创建一个接口Builder,用于创建两个零件,并有一个返回产品的方法用于返回产品(
builder的意思是建造者或者建筑工人。例如:楼房是千差万别的,楼房的外形,层数,内部房间的数量,房间的装饰都不一样。但是对于建造者来说,抽象出来的建筑流程是确定的。因为建筑一座楼房,都可以归纳为几个步骤:1打桩、2建地基、3搭框架、4内部建设。同理,建造者设计模式也是基于这样的概念而生的,这个设计模式用来解决什么样的情况呢:即流程不变,但每个流程实现的具体细节是会变化的。这样的情况,可以考虑使用建造者。就像盖房子,4个流程都必须有,但每个流程各自的实现细节,各个房子各有不同。建造者模式的好处就是保证了流程不会变化,即流程不会增加也不会遗漏,也不会产生流程次序的错误。这是非常重要的,看新闻,一些楼歪歪的事件,很多都是建设楼盘的时候,流程出现了问题导致的。(看来这些人并不知道建造者模式啊)。而建造者模式,保证了流程的确定性,而流程内部的实现细节,是可继承扩展的。从根源上解决了流程不规范的问题。)
创建具体建造类ConcreteBuilder具体实现Builder里的方法。
创建一个导演类,导演类持有一个Builder引用,这样在construct方法里可以调用builder.buildPart1()和builder.buildPart2()来创建产品
最后在客户端调用就好了,放上客户端代码
public class Client {
public static void main(String[]args){
Builder builder = new ConcreteBuilder();
Director director = new Director(builder);
director.construct();
Product product = builder.retrieveResult();
System.out.println(product.getPart1());
System.out.println(product.getPart2());
}
}
好了,多说无益,上实例
首先创建一个People类(相当于产品)
public class People {
private String foot;
private String hand;
public String getFoot() {
return foot;
}
public void setFoot(String foot) {
this.foot = foot;
}
public String getHand() {
return hand;
}
public void setHand(String hand) {
this.hand = hand;
}
}
然后创建一个天使接口(相当于builder)和具体的天使类,天使A(相当于具体builder)
public interface TianShi {
public void CreateFoot();
public void CreateHand();
public People returnPeople();
}
public class TianShiA implements TianShi{
private People people=new People();
@Override
public void CreateFoot() {
people.setFoot("麒麟脚");
}
@Override
public void CreateHand() {
people.setHand("右手麒麟臂");
}
@Override
public People returnPeople() {
return people;
}
}
再创建一个God类(相当于direct),在创人之初,天使造了个只有脚的人,后来发现不行啊,少了点什么,不能自己嘿嘿嘿(脑补费玉清)后来就造了手,后来,上帝规范了流程,造人先造脚,再造手。
public class God {
private TianShi tianShi;
public God(TianShi tianShi) {
this.tianShi=tianShi;
}
public void CreatePeople(){
tianShi.CreateFoot();
tianShi.CreateHand();
System.out.println("流程正确");
}
}
最后写一个Client类
public class Client {
public static void main(String[] args) {
TianShi tianShi=new TianShiA();
God god=new God(tianShi);
god.CreatePeople();
People people=tianShi.returnPeople();
System.out.println(people.getFoot());
System.out.println(people.getHand());
}
}
输出结果:
流程正确
麒麟脚
右手麒麟臂
麒麟脚
右手麒麟臂
(以下内容摘自上面两个链接)
建造模式分成两个很重要的部分:
1. 一个部分是Builder接口,这里是定义了如何构建各个部件,也就是知道每个部件功能如何实现,以及如何装配这些部件到产品中去;2. 另外一个部分是Director,Director是知道如何组合来构建产品,也就是说Director负责整体的构建算法,而且通常是分步骤地来执行。
不管如何变化,建造模式都存在这么两个部分,一个部分是部件构造和产品装配,另一个部分是整体构建的算法。认识这点是很重要的,因为在建造模式中,强调的是固定整体构建的算法,而灵活扩展和切换部件的具体构造和产品装配的方式。
再直白点说,建造模式的重心在于分离构建算法和具体的构造实现,从而使得构建算法可以重用。具体的构造实现可以很方便地扩展和切换,从而可以灵活地组合来构造出不同的产品对象
使用建造者模式的好处
1.使用建造者模式可以使客户端不必知道产品内部组成的细节。2.具体的建造者类之间是相互独立的,对系统的扩展非常有利。
3.由于具体的建造者是独立的,因此可以对建造过程逐步细化,而不对其他的模块产生任何影响。
在什么情况下使用建造模式
1. 需要生成的产品对象有复杂的内部结构,每一个内部成分本身可以是对象,也可以仅仅是一个对象(即产品对象)的一个组成部分。2. 需要生成的产品对象的属性相互依赖。建造模式可以强制实行一种分步骤进行的建造过程,因此,如果产品对象的一个属性必须在另一个属性被赋值之后才可以被赋值,使用建造模式是一个很好的设计思想。
3. 在对象创建过程中会使用到系统中的其他一些对象,这些对象在产品对象的创建过程中不易得到。