12.设计模式之建造者模式

1. 定义:

将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。

2. 

四个要素

  • 产品类:一般是一个较为复杂的对象,也就是说创建对象的过程比较复杂,一般会有比较多的代码量。在本类图中,产品类是一个具体的类,而非抽象类。实际编程中,产品类可以是由一个抽象类与它的不同实现组成,也可以是由多个抽象类与他们的实现组成。
  • 抽象建造者:引入抽象建造者的目的,是为了将建造的具体过程交与它的子类来实现。这样更容易扩展。一般至少会有两个抽象方法,一个用来建造产品,一个是用来返回产品。
  • 建造者:实现抽象类的所有未实现的方法,具体来说一般是两项任务:组建产品;返回组建好的产品。
  • 导演类:负责调用适当的建造者来组建产品,导演类一般不与产品类发生依赖关系,与导演类直接交互的是建造者类。一般来说,导演类被用来封装程序中易变的部分。

例子:

         通过导演类得到小汽车和公交车这两个车的产品。

         ps: 我把产品类分成了Bus和Car两个产品,但是还是通过一个builder类来进行构建。就是把builder中的setProduct方法用反射来实现

1. Bus对象

/**
 * 公共汽车对象
 * 
 * @author king
 *
 */
public class Bus {

	private String name;

	private String type;

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getType() {
		return type;
	}

	public void setType(String type) {
		this.type = type;
	}

	@Override
	public String toString() {
		System.out.println("Bus名: " + this.getName() + "--Bus类型: "
				+ this.getType());
		return null;
	}

}

 2. Car对象

/**
 * 小汽车对象
 * 
 * @author king
 *
 */
public class Car {
	private String name;
	private String type;

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getType() {
		return type;
	}

	public void setType(String type) {
		this.type = type;
	}

	@Override
	public String toString() {
		System.out.println("Car名: " + this.getName() + "--Car类型: "
				+ this.getType());
		return null;
	}

}

 3.抽象建造者

import java.util.Map;

/**
 * 抽象建造者类
 * 
 * @author king
 *
 */

public abstract class Builder {
	
	//设置产品
	abstract void setProduct(Class clazz,Map setMap);
	//返回产品
	abstract Object getProduct();
	
}

 4.具体建造者

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Iterator;
import java.util.Map;

/**
 * 具体建造者类
 * 
 * @author king
 * 
 */
public class ConcreteBuilder extends Builder {
	private Object obj = null;;
	//用反射的方法得到实例化的产品
	void setProduct(Class clazz, Map setMap) {
		try {
			obj = clazz.newInstance();
			Field[] fields = clazz.getDeclaredFields();
			for (int i = 0; i < fields.length; i++) {
				Field field = fields[i];
				String fieldName = field.getName();
				String stringLetter = fieldName.substring(0, 1).toUpperCase();
				String setName = "set" + stringLetter + fieldName.substring(1);
				if (setMap.containsKey(fieldName)) {
					Method setMethod = clazz.getMethod(setName,
							new Class[] { field.getType() });
					setMethod.invoke(obj,
							new Object[] { setMap.get(fieldName) });
				}
			}
		} catch (Exception e) {
			e.getMessage();
		}
	}

	Object getProduct() {
		return obj;
	}
}

 5.导演类

import java.util.HashMap;
import java.util.Map;


/**
 * 导演类,返回请求对象
 * 
 * @author king
 *
 */
public class Director {

	private Builder builder = new ConcreteBuilder();

	Object getProductOfBus() {
		Map attributeMap = new HashMap();
		attributeMap.put("name", "bus");
		builder.setProduct(Bus.class,attributeMap);
		Object obj = builder.getProduct();
		return obj;
	}
	Object getProductOfCar() {
		Map attributeMap = new HashMap();
		attributeMap.put("name", "car");
		builder.setProduct(Car.class,attributeMap);
		Object obj = builder.getProduct();
		return obj;
	}
}

 6. 主方法入口

/**
 * 程序入口方法
 * 
 * @author king
 *
 */
public class Main {
	public static void main(String[] args) {
		//实列化导演类
		Director director = new Director();
		//我需要得到小汽车这个产品
		Object car = director.getProductOfCar();
		car.toString();
		//我需要得到公共汽车这个产品
		Object bus = director.getProductOfBus();
		bus.toString();
	}
}

 运行结果

Car名: car--Car类型: null

Bus名: bus--Bus类型: null

 

我们发现,当再需要一个产品的时候,只需要添加一个产品类,并且在导演类中添加构造该类的方法,不需要做其它操作了

 

总结

      建造者模式与工厂模式类似,他们都是建造者模式,适用的场景也很相似。一般来说,如果产品的建造很复杂,那么请用工厂模式;如果产品的建造更复杂,那么请用建造者模式。

 

文章参考: <http://blog.csdn.net/java7star/article/details/9092871>此处致谢

返回导航

  

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值