论坛首页 Java企业应用论坛

Deep Thinking in Patterns--工厂方法模式(Factory Method)

浏览 6301 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2007-02-10  
工厂方法模式属于创建模式,也是关于如何创建对象的模式。是对简单工厂模式的改进。简单模式中工厂处于核心位置,对于复杂的层次对象显得过于复杂,缺乏扩展性。即做不到“开-闭”原则。如果有新产品加入到系统,需要须改工厂,加入创建逻辑。工厂模式则巧妙的避开了这点,并且把创建责任推迟到子类。
另外,工厂方法的这个技术(虚拟创建推迟到子类)对开发系统框架非常有用。
 
1.工厂方法模式中涉及的角色
   抽象工厂,具体工厂,抽象产品具体产品。
 
把简单工厂中的工厂对象分派成多个具体工厂,每一个具体工厂负责创建一个具体的产品。和客户端直接创建具体产品相比较,运用工厂方法做到了对客户端透明,即客户端得到的一个抽象产品的具体实例,而不需要明确的知道真正的具体产品。同时克服了简单工厂的开闭原则问题。做到了有新产品加入无需修改工厂核心类,只需要新加入具体工厂即可。给人感觉上隐藏了对体的产品,但却暴露了具体的工厂,使得一个具体产品对应一个具体工厂,但实际上大多数情况这些具体工厂可能是由客户端本身去定义创建的,所以也比较合理。
 
 
2. 工厂方法模式使用的前提
 
1>     有创建一批有相同接口对象的需求
2>     不想暴露太多类的细节给使用者,或者隐藏对象的创建工作
1>       产品的等级机构比较复杂,使用简单工厂模式可能会造成扩展性问题
4>     当一个不知道他必须创建的类的时候,或者一个希望由他的子类制定他所创建的对象的时候。举个例子:系统框架使用抽象类定义,创建和维护对象之间的关系,但通常这些具体的类需要有客户端来具体化,对于框架无法知道具体子类的情况下,使用工厂模式来进行框架的开发维护。所以,工厂模式也被称作“虚拟构造器
 
所以对于使用工厂方法模式优化简单工厂模式,如:在聚集中Collection工厂方法iterator()返回Iterator对象,Collection其实就是抽象工厂,Iterator就是抽象产品,每个派生于Collection的聚集对象必须实现iterator()返回自己具体的Iterator实现,如ArrayList。其中每个子聚集类就是具体工厂,他们自己实现如何返回抽象对象,对客户端来说返回的产品还是透明的抽象产品。
客户端此时需要创建具体的工厂,如具体的聚集对象ArrayList,Hashtable等具体工厂,其实这些对象主要工作是容器,至于作为具体工厂只是其一个小功能,所以直接暴露很多具体工厂这里也是ok的。其实如果一个接口A返回另一个接口或者抽象对象B,可以说这个接口A是一个抽象工厂,实现这个接口的类是具体工厂。这么一说,是不是感觉我们平时很多地方已经自觉不自觉地运用了工厂模式呢?哈哈
 
其实个人认为,工厂方法模式如果处理上述的第4类问题,可能更像是工厂方法。比如:一个文档处理框架,中有抽象的Application负责整个文档的管理,Document为一个抽象的文档,我们需要管理整个文档的流程,比如文档的新建,等等,这样我们需要知道具体的文档类了,但其实我们是无法知道我们的User到底会创建什么类,此时工厂方法模式就派上了用场。
我们在抽象的Application中定义了工厂方法:CreateDocument();这样在具体的子类中就可以具体实现如何创建了。此时我们在Application就可以完成我们的框架如OpenDocument()NewDocumet()等这类工作了。
 
3.工厂方法模式的优点缺点
优点:
1>     优化了简单工厂模式,做到了“开-闭”原则。
2>     可以做到把具体的产品创建过程延迟的具体的子类工厂,使得基类工厂可以基于工厂方法创建的抽象对象工作。
缺点:
1> 暴露具体工厂,但多数情况这不会造成问题,尤其是对于虚拟构造器,就显得更加合理。
 
4.备注
1> 对于工厂方法模式子类创建的模式,有点让大家联想到模版模式,其主要区别是工厂方法模式主要目的是把创建工作推迟到子类,而模版模式则是把剩余的逻辑交给子类。这二者也可以结合起来使用。

   发表时间:2007-02-20  
和客户端直接创建具体产品相比较,运用工厂方法做到了对客户端透明,即客户端得到的一个抽象产品的具体实例,而不需要明确的知道真正的具体产品。同时克服了简单工厂的开闭原则问题。做到了有新产品加入无需修改工厂核心类,只需要新加入具体工厂即可。给人感觉上隐藏了对体的产品,但却暴露了具体的工厂,使得一个具体产品对应一个具体工厂,但实际上大多数情况这些具体工厂可能是由客户端本身去定义创建的,所以也比较合理。

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

我看这句话,怎么看怎么矛盾,“但实际上大多数情况这些具体工厂可能是由客户端本身去定义创建的”,既然这样,那么客户端肯定要知道产品类是怎么创建的,这样怎么去隐藏产品类的创建细节?怎么对客户端透明?

我不知道使用工厂模式是怎么符合开闭原则的,同样是要客户端添加新的工厂类,这和直接使用抽象产品有什么区别?
0 请登录后投票
   发表时间:2007-02-21  
适当的加个简单的工厂模式例子效果会更好
0 请登录后投票
   发表时间:2007-04-02  
麻烦麻烦,不用是理解不了了!
0 请登录后投票
   发表时间:2007-04-02  
工厂模式只是在[抽象产品]可能拥有多个不同实现,也就是说抽象产品的实现经常变化的时候才比较有优势,因为工厂构造出来的产品调用者是不需要关心的!

但是如果是不停的增加新的产品,好像看不到工厂模式有哪些扩展性方面的优势。

也就是说对于产品的实现变化有点符合开-闭原则,
但是对于产品的添加好象就.....
0 请登录后投票
   发表时间:2007-04-02  
模式这东西得用到实际开发当中才能记得牢啊,另外没有代码,看这些抽象的东西也不好理解
0 请登录后投票
   发表时间:2007-08-08  
要想弄明白,关键是在实战中去摸索体会!!
0 请登录后投票
   发表时间:2007-08-14  
lz把简单的东西搞复杂了
0 请登录后投票
论坛首页 Java企业应用版

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