论坛首页 Java企业应用论坛

java设计模式全解[4]-工厂方法模式

浏览 7815 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2007-06-13  

工厂方法模式

概述
    在软件系统中,经常面临着“某个对象”的创建工作,由于需求的变化,这个对象的具体实现经常面临着剧烈的变化,但是它却拥有比较稳定的接口。如何应对这种变化?提供一种封装机制来隔离出“这个易变对象”的变化,从而保持系统中“其它依赖该对象的对象”不随着需求的改变而改变?这就是要说的Factory Method模式了。
意图
    定义一个用户创建对象的接口,让子类决定实例化哪一个类。Factory Method使一个类的实例化延迟到其子类。

生活中的例子
     工厂方法定义一个用于创建对象的接口,但是让子类决定实例化哪个类。压注成型演示了这种模式。塑料玩具制造商加工塑料粉,将塑料注入到希望形状的模具中。玩具的类别(车,人物等等)是由模具决定的。

工厂方法解说
    在工厂方法模式中,核心的工厂类不再负责所有产品的创建,而是将具体创建工作交给子类去做。这个核心类仅仅负责给出具体工厂必须实现的接口,而不接触哪一个产品类被实例化这种细节。这使得工厂方法模式可以允许系统在不修改工厂角色的情况下引进新产品。在Factory Method模式中,工厂类与产品类往往具有平行的等级结构,它们之间一一对应。
zmo_xu在这里举一个简单的例子:核心工厂就好比KFC的总店,其不在负责鸡块,汉堡的生成,而是交给加盟的分店去生成,总店(核心类)仅仅负责给出分店加工食品所必须经过的步骤(必须实现的接口)而不基础食品制作(实例化).这样在不修改总店的情况下就可以直接接受新的加盟分店[不知道这样理解行得通不呵呵]
现在我们考虑一个日志记录的例子(这里我们只是为了说明Factory Method模式,实际项目中的日志记录不会这么去做,也要比这复杂一些)。假定我们要设计日志记录的类,支持记录的方法有FileLog和EventLog两种方式。在这里我们先不谈设计模式,那么这个日志记录的类就很好实现了:
[未完待续]

   发表时间:2007-06-13  
赞一个


---------------------
java资料站点
www.sunjava.cn
0 请登录后投票
   发表时间:2007-06-13  
好像还没写完?
0 请登录后投票
   发表时间:2007-07-08  
工厂方法一般的出现形态是这样的:
public voic xx(){
   ...
   createProduct();//调用工厂方法
   ...
}

abstract protected Product createProduct();

工厂方通常不会被client调用,而是由xx()方法自己消化,我把他叫"自产自消",这一点是跟其他创建模式最大的区别.所以一般工厂方法都是定义为protected.

下面这些代码是来自一个通用树构造组件里的,可以参考下.
http://www.iteye.com/topic/98668
public TreeModel create(Collection pUserDatas, UserDataUncoder pUncoder)
			throws CreateTreeModelException {
		if (pUserDatas == null) {
			return new DefaultTreeModel();
		}
		if ( pUserDatas.isEmpty() ){
			return new DefaultTreeModel();
		}
		if (pUncoder == null) {
			throw new CreateTreeModelException("节点解码器不能为空null");
		}
		DefaultTreeModel result = new DefaultTreeModel();
		Map nodes = new HashMap();
		Iterator userDatasIterator = pUserDatas.iterator();
		while (userDatasIterator.hasNext()) {
			Object userData = userDatasIterator.next();
			Object id = null;
			try {
				id = pUncoder.getID(userData);
			} catch (UncodeException ex) {
				throw new CreateTreeModelException(ex.getMessage(), ex);
			}
			if ( id == null ){
				throw new CreateTreeModelException("获取用户ID失败,用户对象:" + userData);
			}
			Node node = null;
			try {
				node = createNode(userData, pUncoder);
			} catch (Exception ex) {
				throw new CreateTreeModelException(ex.getMessage(), ex);
			}
			if ( node == null ){
				log.warn("创建节点失败,用户对象:" + userData);
				continue;
			}
			node.setUserData(userData);
			nodes.put(id, node);//将节点cache起来
		}

		Iterator nodeIterator = nodes.values().iterator();
		while (nodeIterator.hasNext()) {
			Node node = (Node) nodeIterator.next();
			Object userData = node.getUserData();
			Object parentId = null;
			try {
				parentId = pUncoder.getParentID(userData);
			} catch (UncodeException ex) {
				throw new CreateTreeModelException(ex.getMessage(), ex);
			}
			Node parentNode = (Node) nodes.get(parentId);
			if (parentNode == null) {//跟节点
				result.addRootNode(node);
				continue;
			}
			node.setParent(parentNode);
		}
		
		if (result.getRootNodeCount() == 0) {
			throw new CreateTreeModelException("不存在跟节点");
		}
		
		if ( allowMutiRoot == false ){
			if ( result.getRootNodeCount() > 1 ){
				throw new MultiRootNodeException();
			}
		}
		 return result;
	}
 
	protected abstract Node createNode(Object pUserData, UserDataUncoder pUncoder);
0 请登录后投票
   发表时间:2007-08-15  
呵呵 javastudy  麻烦你了 ...在帮我补全啊  ..最近很忙一直都没空上 ..最近 中招了 签了一个有点黑的公司  呵呵  估计最近会有点空 想抽空把这些写完  ...好像2个月没来了
0 请登录后投票
   发表时间:2007-09-04  
不知道楼主可不可以深入分析下PROTOTYPE模式,我对这个不是很了解,谢谢。
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics