浅学设计模式之建造者(Buildler Pattern)模式及在android中的应用

        被自己用一根香蕉收买后,舒舒服服的洗完澡以后,认认真真的做完50多个仰卧起坐以后,在得到自己想要的消息后,好吧,不管是无意或者有意。好吧,现在就将近12点了,关于建造者模式,是今天自己再看刘伟老师的设计模式PPT的时候学习的,在《Head First 设计模式》那本书里是没有讲这个建造者模式,好吧,再一次说明,关于设计模式系列文章的文字部分大部分是从网上整理而来,代码部分由自己完成,因为自我感觉还没有能力能够系统的解释一个模式,已经有现成的比较完善的说明,就不重复造轮子了。


一、概述:

在软件系统中,有时候面临着“一个复杂对象”的创建工作,其通常由各个部分的子对象用一定的算法构成;由于需求的变化,这个复杂对象的各个部分经常面临着剧烈的变化,但是将它们组合在一起的算法确相对稳定。如何应对这种变化?如何提供一种“封装机制”来隔离出“复杂对象的各个部分”的变化,从而保持系统中的 “稳定构建算法”不随着需求改变而改变?这就是要说的建造者模式。


二、定义:

建造者模式(Builder Pattern)也叫生成器模式,其定义如下:
separate the construction of a complex object from its representation so that the same construction process can create different representations.将一个复杂对象的构建与它的标示分离,使同样的构建过程刻意创建不同的表示。

三、类图:



  1. 建造者(Builder)角色:给出一个抽象接口,以规范产品对象的各个组成成分的建造。一般而言,此接口独立于应用程序的商业逻辑。模式中直接创建产品对象的是具体建造者(Concrete Builder)角色。具体建造者类必须实现这个接口所要求的方法:一个是建造方法,另一个是结果返还方法。
  2. 具体建造者(Concrete Builder)角色:担任这个角色的是于应用程序紧密相关的类,它们在应用程序调用下创建产品实例。这个角色主要完成的任务包括:实现Builder角色提供的接口,一步一步完成创建产品实例的过程。在建造过程完成后,提供产品的实例。
  3. 指导者(Director)角色:担任这个角色的类调用具体建造者角色以创建产品对象。导演者并没有产品类的具体知识,真正拥有产品类的具体知识的是具体建造者对象。
  4. 产品(Product)角色:产品便是建造中的复杂对象。指导者角色是于客户端打交道的角色。导演者角色将客户端创建产品的请求划分为对各个零件的建造请求,再将这些请求委派给具体建造者角色。具体建造者角色是做具体建造工作的,但却不为客户端所知。


四、代码示例

以食物为例,感觉着例子写的不好,凑合着看下:
先看Product:
public class Food {
	private String mFoodName;
	private String mFoodTastes;
	private String mFoodFeatures;
	private String mChillies;
	private String mSugar;
	private String mSalt;
	
	public void setFoodName(String name) {
		mFoodName = name;
	}
	
	public String getFoodName() {
		return mFoodName;
	}
	
	public void setFoodTastes(String tastes) {
		mFoodTastes = tastes;
	}
	
	public String getFoodTastes() {
		return mFoodTastes;
	}
	
	public void setFoodFeatures(String features) {
		mFoodFeatures = features;
	}
	
	public String getFoodFeatures() {
		return mFoodFeatures;
	}
	
	public String getChillies() {
		return mChillies;
	}

	public void setChillies(String mChillies) {
		this.mChillies = mChillies;
	}

	public String getSugar() {
		return mSugar;
	}

	public void setSugar(String mSugar) {
		this.mSugar = mSugar;
	}
	
	public String getSalt() {
		return mSalt;
	}
	
	public void setSalt(String salt) {
		mSalt = salt;
	}
	

	@Override
	public String toString() {
		return "Food Name: " + getFoodName() + "\r\n" 
		+ "Food Feature: " + getFoodFeatures() + "\r\n"
		+ "Food Tastes: " + getFoodTastes() + "\r\n"
		+ "Food Chillies: " + getChillies() + "\r\n"
		+ "Food Salt: " + getSalt() + "\r\n"
		+ "Food Sugar: " + getSugar();
	}
}

上面菜肴中各种属性,比较简单,就是一个实体类。
下面是Builder:
public abstract class Builder {
	
	protected Food mFood = new Food();
	
	public abstract void setFoodName(String name);
	public abstract void setFoodTastes(String tastes);
	public abstract void setFoodFeature(String feature);
	public abstract void addSugar(String sugar);
	public abstract void addSalt(String salt);
	public abstract void addChillies(String chillies);
	
	
	public Food getResult() {
		return mFood;
	}
}

实体Builder:
public class ShandongCuisineChefBuilder extends Builder{

	@Override
	public void setFoodName(String name) {
		mFood.setFoodName(name);
	}

	@Override
	public void setFoodTastes(String tastes) {
		mFood.setFoodTastes(tastes);
	}

	@Override
	public void setFoodFeature(String feature) {
		mFood.setFoodFeatures(feature);
	}

	@Override
	public void addSugar(String sugar) {
		mFood.setSugar(sugar);
	}

	@Override
	public void addSalt(String salt) {
		mFood.setSalt(salt);
	}

	@Override
	public void addChillies(String chilies) {
		mFood.setChillies(chilies);
	}

}

public class SiChuanChefBuilder extends Builder {

	@Override
	public void setFoodName(String name) {
		mFood.setFoodName(name);
	}

	@Override
	public void setFoodTastes(String tastes) {
		mFood.setFoodTastes(tastes);
	}

	@Override
	public void setFoodFeature(String feature) {
		mFood.setFoodFeatures(feature);
	}

	@Override
	public void addSugar(String sugar) {
		mFood.setSugar(sugar);
	}

	@Override
	public void addSalt(String salt) {
		mFood.setSalt(salt);
	}

	@Override
	public void addChillies(String chilies) {
		mFood.setChillies(chilies);
	}
	

}

这两个大厨类写的有点多余,因为实现完全一样。
director类:
public class Director {
	private Builder mBuilder;
	
	public Director(){}
	
	public Director(Builder builder) {
		mBuilder = builder;
	}
	
	public void setDirector(Builder builder) {
		mBuilder = builder;
	}
	
	public Food construct(String name, String feature, String tastes,
			String chillies, String salt, String sugar) {
		mBuilder.setFoodName(name);
		mBuilder.setFoodFeature(feature);
		mBuilder.setFoodTastes(tastes);
		mBuilder.addChillies(chillies);
		mBuilder.addSalt(salt);
		mBuilder.addSugar(sugar);
		return mBuilder.getResult();
	}
	
}

client类:
public class Client {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		Builder shandongCuisineChef = new ShandongCuisineChefBuilder();
		Builder siChuanChef = new SiChuanChefBuilder();
		
		Director director = new Director(shandongCuisineChef);
		Food food = director.construct("糖醋里脊", "色淡黄,形光润饱满.外松脆酥香,里软嫩鲜美", "又甜又香", "无", "适量", "加糖");
		
		System.out.println("经典鲁菜: " + "\r\n" + food);
		
		Director director2 = new Director();
		director2.setDirector(siChuanChef);
		Food food2 = director2.construct("水煮肉片", "肉味香辣,软嫩,易嚼", "麻、辣、鲜、烫", "多", "适量", "无");
		System.out.println("经典川菜: " + "\r\n" + food2);
		
	}

}

程序运行结果:
经典鲁菜: 
Food Name: 糖醋里脊
Food Feature: 色淡黄,形光润饱满.外松脆酥香,里软嫩鲜美
Food Tastes: 又甜又香
Food Chillies: 无
Food Salt: 适量
Food Sugar: 加糖
经典川菜: 
Food Name: 水煮肉片
Food Feature: 肉味香辣,软嫩,易嚼

还算比较简单,不做过多解释了。

五、应用

1. 建造者模式的优点

  • 封装性

      使用建造者模式可以使客户端不必知道产品内部组成的细节,如例子中我们就不需要关心每一个具体的模型内部是如何实现的,产生的对象类型就是CarModel。

  • 建造者独立,容易扩展

      Builder之间是相互独立的,与其它的Builder无关,对系统的扩展非常有利。

  • 便于控制细节风险

      模式所建造的最终产品更易于控制:由于具体的建造者是独立的,因此可以对建造过程逐步细化,而不对其他的模块产生任何影响。

2. 建造者模式的使用场景

  • 相同的方法,不同的执行顺序,产生不同的事件结果时,可以采用建造者模式,需要生成的产品对象的属性相互依赖,建造者模式可以强迫生成顺序
  • 多个部件或零件,都可以装配到一个对象中,但是产生的运行结果又不相同时,则可以使用该模式。
  • 产品类非常复杂,或者产品类中的调用顺序不同产生了不同的效能,这个时候使用建造者模式是非常合适。
  • 在对象创建过程中会使用到系统中的一些其它对象,这些对象在产品对象的创建过程中不易得到时,也可以采用建造者模式封装该对象的创建过程。该种场景,只能是一个补偿方法,因为一个对象不容易获得,而在设计阶段竟然没有发觉,而要通过创建者模式柔化创建过程,本身已经违反设计最初目标。

3. 建造者模式的注意事项

      建造者模式关注的是的零件类型和装配工艺(顺序),这是它与工厂方法模式最大不同的地方,虽然同为创建类模式,但是注重点不同。

六、和其他模式的区别:

     
  1. 与抽象工厂模式相比,建造者模式返回一个组装好的完整产品,而抽象工厂模式返回一系列相关的产品,这些产品位于不同的产品等级结构,构成了一个产品族
  2. 在抽象工厂模式中,客户端实例化工厂类,然后调用工厂方法获取所需产品对象,而在建造者模式中,客户端可以不直接调用建造者的相关方法,而是通过指挥者类来指导如何生成对象,包括对象的组装过程和建造步骤,它侧重于一步步构造一个复杂对象,返回一个完整的对象
  3. 如果将抽象工厂模式看成汽车配件生产工厂,生产一个产品族的产品,那么建造者模式就是一个汽车组装工厂,通过对部件的组装可以返回一辆完整的汽车。  

七、在android中的应用

Dialog:Dialog的建造过程就是一个典型的“建造者模式”,通过Builder来设置不同的参数,创建出不同的Dialog。好吧,下一篇文章分析Dialog和Builder的源码。


评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值