被说了很多遍的设计模式---建造者模式

[把你的理性思维慢慢变成条件反射]

本文,我们讲介绍建造者模式,文章主题结构与上文一致。惯例,先来看看我们示例工程的环境:

操作系统:win7 x64

其他软件:eclipse mars,jdk7

-------------------------------------------------------------------------------------------------------------------------------------

经典问题:

将某个过程进行抽象、一个复杂对象,流程的创建,执行过程,等“具体某个‘产品’的‘生产过程’”

思路分析:

要点一:对象需要经历多个步骤才能生成。

要点二:这个步骤,过程能够抽象,或者,过程处理具有相似性。

示例工程:

本文以建造一个机器人为例。


错误写法:

创建RobotABuilder.java,RobotBBuilder.java文件,具体内容如下:

package com.csdn.ingo.gof_builder;

public class RobotABuilder {
	private String panel;
	private String color;
	public RobotABuilder(String panel, String color) {
		this.panel = panel;
		this.color = color;
	}
	public void build() {
		System.out.println("panel:"+panel);
		System.out.println("color:"+color);
		System.out.println("step1:head");
		System.out.println("step2:body");
		System.out.println("step3:limb");
	}
}
创建Window.java文件,具体内容如下:
package com.csdn.ingo.gof_builder;

public class Window {
	public static void main(String[] args) {
		RobotBBuilder t = new RobotBBuilder("white", "red");
		t.build();
		
		RobotABuilder f = new RobotABuilder("black", "blue");
		f.build();
	}
}

错误原因:

RobotA,RobotB具有相似的创建过程。但是,上面的创建代码完全没有做出应有的抽象整合,造成较多的冗余代码。

推荐写法:



创建RobotBuilder.java文件,具体内容如下:

package com.csdn.ingo.gof_builder.one;

public abstract class RobotBuilder {
	protected String panel;
	protected String color;
	
	public RobotBuilder(String panel,String color){
		this.panel = panel;
		this.color = color;
	}
	public abstract void buildHead();
	public abstract void buildBody();
	public abstract void buildlimb();
}
创建RobotDirector.java文件,具体内容如下:

package com.csdn.ingo.gof_builder.one;

public class RobotDirector {
	private RobotBuilder pb;

	public RobotDirector(RobotBuilder pb) {
		this.pb = pb;
	}
	public void createPerson(){
		pb.buildHead();
		pb.buildBody();
		pb.buildlimb();
	}
}
创建RobotABuilder.java,RobotBBuilder.java文件,具体内容如下:

package com.csdn.ingo.gof_builder.one;

public class RobotABuilder extends RobotBuilder {
	
	public RobotABuilder(String panel, String color) {
		super(panel, color);
	}
	@Override
	public void buildHead() {
		// TODO Auto-generated method stub
		System.out.println("A step1:head");
	}
	@Override
	public void buildBody() {
		// TODO Auto-generated method stub
		System.out.println("A step2:body");
	}
	@Override
	public void buildlimb() {
		// TODO Auto-generated method stub
		System.out.println("A step3:limb");
	}
}
创建Window.java文件,具体内容如下:

package com.csdn.ingo.gof_builder.one;

public class Window {
	public static void main(String[] args) {
		RobotBBuilder p = new RobotBBuilder("white", "red");
		RobotDirector pd = new RobotDirector(p);
		pd.createPerson();
		
		RobotABuilder pf = new RobotABuilder("black", "blue");
		RobotDirector pdf = new RobotDirector(pf);
		pdf.createPerson();
	}
}

推荐原因:

这种写法区分出了,对象创建过程中的可变过程与不变过程。使客户端明确的感受到对象创建过程中必须传入的内容,必须实现的过程。更加有利于模型改变的表达。

模式总结:

标准建造者模式UML结构图:


概念总结:

建造者模式:讲一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。

组成部分:Director(指挥者,具体的步骤设计)。Builder(建造者抽象接口类)。ConcreteBuilder(具体步骤实现类)。Product.java(具体产品)四部分组成。

模板代码:


创建Builder.java文件,具体内容如下:

package com.csdn.ingo.gof_builder.two;

public abstract class Builder {
	public abstract void buildPartA();
	public abstract void buildPartB();
	public abstract void buildPartC();
	public abstract Product getResult();
}
创建ConcreteBuilder1.java,ConcreteBuilder2.java文件,具体内容如下:

package com.csdn.ingo.gof_builder.two;

public class ConcreteBuilder1 extends Builder{
	private Product p = new Product();

	@Override
	public void buildPartA() {
		// TODO Auto-generated method stub
		p.add("part-A");
	}

	@Override
	public void buildPartB() {
		// TODO Auto-generated method stub
		p.add("part-B");
	}

	@Override
	public void buildPartC() {
		// TODO Auto-generated method stub
		p.add("part-C");
	}

	@Override
	public Product getResult() {
		// TODO Auto-generated method stub
		return p;
	}
	
}
创建Director.java文件,具体内容如下:
package com.csdn.ingo.gof_builder.two;

public class Director {
	public void Construct(Builder builder){
		builder.buildPartA();
		builder.buildPartB();
		builder.buildPartC();
	}
}
创建Product.java文件,具体内容如下:

package com.csdn.ingo.gof_builder.two;

import java.util.ArrayList;
import java.util.List;

public class Product {
	List<String> parts = new ArrayList<String>();
	public void add(String part) {
		parts.add(part);
	}
	public void show() {
		System.out.println("---list---");
		for(String part:parts){
			System.out.println(part);
		}
	}
}
特别的:一般情况下Product为Java对象时,多为值对象等,如下:
public class Product  {
       private  String partA; //定义部件,部件可以是任意类型,包括值类型和引用类型
       private  String partB;
       private  String partC;
       //partA的Getter方法和Setter方法省略
       //partB的Getter方法和Setter方法省略
       //partC的Getter方法和Setter方法省略
}
另外,可以将Director中的Construst方法增加返回值,方便客户端使用。

模板功能扩展:

  1. 将Director与Builder进行合并。(Builder为抽象类,可将construst方法变为静态方法,放入到Builder中)
  2. 如果在客户端没有传入参数的条件下,可以在第一条的基础上,将construst方法的参数直接移除,改为直接调用Builder本身的方法即可。
  3. 为了精确的控制到某一个具体的创建方法时候执行,可以引入我们在前文中介绍的钩子方法。(即,在Builder抽象类中增加一个布尔型的钩子方法,并赋予默认值,然后在其子类当中,重写该方法,并在相应的具体方法上增加钩子方法的判断,即可实现方法界别的精确控制。)

反思:

应用场景:

  1. 需要创建的对象拥有复杂的内部结构,通常情况下其包含有多个成员变量。
  2. 对象属性间存在依赖关系,即可能需要执行生成顺序。
  3. 创建过程可以从对象所属的类当中独立出来。即Product的创建过程抽象在Director中。
  4. 隔离复杂对象的创建和使用,并且使得相同的过程可以创建不同的产品。

优点:

  1. 细节依赖于抽象。向客户端屏蔽整个对象的创建过程,并且创建过程本身依赖抽象,保证对象创建过程一致性。
  2. 具体的建造者可以存在多个,并且每一个具体的建造者相互之间保持独立性。增加系统的维护性,扩展性。
  3. 对每一步骤的细节可以更加精确的把控。
  4. 在引入配置文件,反射机制之后,可以动态的,在运行时改变整个建造策略,及相应的结果。

缺点:

  1. 必须要求产品之间存在相同的创建过程。
  2. 必须要求产品具有创建过程上的稳定性,一旦建造过程发生变化,必须修改对应的Director。
  3. 对于数量较多的相似对象,可能存在较多的具体产品类。应当做好抽象工作,防止系统内部出现过多的子类。

-------------------------------------------------------------------------------------------------------------------------------------

至此,被说了很多遍的设计模式---建造者模式 结束


参考资料:

图书:《大话设计模式》

其他博文:http://blog.csdn.NET/lovelion/article/details/7563445


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值