[设计模式之禅读书笔记]008_23种设计模式二:工厂方法模式

   序言

   《设计模式之禅》看到第78页了,继续坚持啊!作为一个创建型的设计模式,工厂方法模式被使用到的频率相当高,因此,这个模式的学习那是相当有价值的。那么,这个模式的定义是怎样的呢?这个模式的实现是怎样的呢?这个模式的作用是怎样的呢?笔者将尽一切可能为读者解释清楚,当然,如果没有解释清楚的,可以一起讨论。这样的学习才有互动性,才能不断进步嘛!元芳,你怎么看?

   正文

   1. 你是怎么创建对象的?(最蠢的方法)

1 // 第一种
2 MyObject mo;
3 
4 // 第二种
5 MyObject *mo = new MyObject();

    靠,躺着也中枪!是的,我就是这么创建对象的啊!用什么创建什么呗,有什么问题吗?太蠢了。是的,从一个软件设计师的角度来看,各种丑陋,就跟山寨平板和ipad的对比一样。其实对于我们这些小猿来说,这样的写法最痛苦的是什么?没有智能提示啊!我要记住那么多个类的名字啊!那要怎么才能有智能提示呢?

   2. 带智能提示的创建对象(简单工厂模式)

 1 class IObject{ // 基类
 2 };
 3 class MyObject:public IObject{ // 具体实现类
 4 };
 5 class MyFactory{ //工厂类
 6 public:
 7     static IObject* createObject(const string& name){
 8         if(name == "MyObject"){
 9             return new MyObject();
10         }else if(name == "YourObject"){
11             ...
12         }else if(name == "HisObject"){
13             ...
14         }
15     }
16 };

    简单吧,用一个MyFactory来封装我们的创建工作就可以了,这样我只需要记住这个工厂——MyFactory的名字就可以了,这样我就可以用MyFactory::来得到智能提示的创建方法了。聪明的你肯定想到了另一个方法,是的,还有一个方法,我们把createObject方法拆开,就可以获取更好的智能提示了,代码如下:

 1 class MyFactory{
 2 public:
 3     static IObject* createMyObject(){ // 创建MyObject,不用记住字符串了
 4         return new MyObject();
 5     }
 6     static IObject* createYourObject(){ // 创建YourObject,不用记住字符串了
 7         return new YourObject();
 8     }
 9     ...
10 };

    这样也可以的,看起来很给力的样子啊!如果我告诉你,你已经掌握了一种设计模式了,你信么?哈哈,恭喜你,你真的学会了一种设计模式了——简单工厂模式。怎样,名副其实的简单吧!可是我们的简单工厂模式有一个问题!

    如果我们有了一个新的类HerObject,怎么办?简单的很,在MyFactory里面追加一个else if判断就可以了,不就加个字符串的事么。对后面的实现来说,不就是加个方法的事的么。屁大点事啊!可是,可是,可是,我们违背了设计模式六大原则的开闭原则(OCP)了,还记得吗?我们追加类的时候,修改了既有类,这怎么办?下面我们来改进一下这个简单工厂。

   3.  改进简单工厂模式(工厂方法模式)

    修改简单工厂模式的目的,就是使得我们新追加对一个新产物生产的工厂时,不会导致原有的代码被更改,看下面的代码:

 1 class IObject{
 2 };
 3 
 4 class MyObject:public IObject{
 5 };
 6 
 7 ...
 8 
 9 class IObjectFactory{
10 public:
11     virtual IObject* createObject(){
12     }
13 };
14 class MyObjectFactory:public IObjectFactory{  // MyObject工厂
15 public:
16     IObject* createObject(){
17         return new MyObject();
18     }
19 };
20 
21 class YourObjectFactory:public IObjectFactory{  // YourObject工厂
22 public:
23     IObject* createObject(){
24         return new YourObject();
25     }
26 };
27 
28 int main(){
29     IObjectFactory* factory = new MyObjectFactory(); // 新建工厂类
30     IObject* myObject = factory->createObject(); // 创建MyObject对象
31 }

    看到好处没?如果我要追加个HisObject类,并且要添加一个生产HisObject的工厂,我只需要追加一个HisObjectFactory类即可,不会对原有的代码造成破坏。这就是我们的工厂方法模式

   4. 回首看一哈子(理论UML图)

       最后,我们总结一下,上面的代码中我们分别实现了两种设计模式——简单工厂模式和工厂方法模式,当然,这两种模式我都没有用上C++的高级语言特性,比如template,不过我们的目的已经达到了,知道了工厂方法模式和简单工厂模式了。下面是两种模式的UML图:

简单工厂模式

      

工厂方法模式

      

   总结

   作为创建型的设计模式,工厂方法模式和简单工厂模式的使用频率是非常高的,掌握这两种设计模式对于我们设计自己的软件系统有很大的好处。不过这两种设计模式也有缺点,当然,缺点是出现在某些极端条件下的。对于我们的软件系统,要选择最适用的模式,就是说没有最好的设计模式,只有最合适的设计模式。

posted @ 2012-10-29 00:31  邵贤军  阅读(1617)  评论(4编辑  收藏  举报