天天好味道

没钱没权没户口,靠走靠吼靠小狗
随笔 - 66, 文章 - 1, 评论 - 524, 引用 - 5

导航

<2006年7月>
2526272829301
2345678
9101112131415
16171819202122
23242526272829
303112345

留言簿(12)

随笔分类

随笔档案

文章档案

我的链接

搜索

最新评论

阅读排行榜

评论排行榜

抽象工厂模式的好处-to 晓寒

本来在写一篇设计模式的体会的文章,不过这个礼拜忙于补习编译原理了,先写一点零碎的吧。
事先申明,以下内容只是我个人的体会,不保证正确,全面以及合理。
--------
在GOF的数量,创建型模式有好几个,最最常用的是工厂方法,简单的描述:
你需要创建很多对象,比如矩形,圆形,圆角矩形(也许这是一个组态软件,或者Visio)。
你可以随地来new,但是稍有经验的人就会选择由一个专门的方法来负责创建对象。如:
CDrawObj* CreateDrawObj(int ObjType)
这样做的好处是显而易见的:
1.代码集中了
2.如果修改了CreateDrawObj函数,可以不影响外部代码。比如CRectDrawObj被认为有问题,有人写了个新
类CRectDrawObjEx,那只要修改CreateDrawObj,就可以神不知鬼不觉地换掉了。

以上的例子,假设我们明白虚函数的概念,CDrawObj就是这么一个虚基类。(C#里更愿意抽象为Interface)

好,现在的代码的情况是:
有一个CreateDrawObj函数,然后其它地方到处散布着对这个函数的调用。
如果现在我有了整个一大套新的DrawObj,而且希望在运行的时刻,可以在两套DrawObj之间切换。
很直观的做法,给CreateDrawObj加一个参数: CDrawObj* CreateDrawObj(int ObjType,int Category)
其实这个办法也挺好的。

不过OO里不太喜欢这一套,我们喜欢把变数封装到对象内部,所以以上函数就变成了两个:
CFactory* CreateFactory(int FactoryType)
CFactory::CreateDrawObj(int ObjType)

这样,当我们希望整个更换DrawObj家族的时候,只要在CreateFactory的时候产生一个不同的工厂就可以了,
其它所有地方不需要修改。而使用 CDrawObj* CreateDrawObj(int ObjType,int Category) 的方式,在每个调用
CreateDrawObj的地方,都要根据情况传入不同的Category参数。

把变数封装到对象中,这是面向对象设计的一个小伎俩。

不知道说清楚了没有。

说实话,抽象工厂用的地方并不是很多,更常见的是工厂方法加模版方法的组合,这在框架设计中比较常用。

posted on 2006-07-25 09:43 jzhang 阅读(2925) 评论(11)  编辑 收藏

评论

# re: 抽象工厂模式的好处-to 晓寒

呵呵,我觉得这个也不是抽象工厂的优点:因为工厂方法就可以完成这点。例如:很多人都吃水果。那么原来大家都吃苹果,现在说西瓜好。那就该吃西瓜了,那很好办,可以如此:

class Fruit
{
};

class Apple: public Fruit
{
};

class Xigua: public Fruit
{
};

class FruitFactory
{
Fruit CreateFruit(string type)
{
...
}
};
2006-07-25 09:54 | 晓寒

# re: 抽象工厂模式的好处-to 晓寒

.... 收到。偶明白了,意思就是工厂换了。这样所有的‘产品’都可以换了。
2006-07-25 09:56 | 晓寒

# 你这个例子不对

抽象工厂模式解决的是:大家只知道在吃西瓜,但是可能是大兴西瓜,也可能是新疆西瓜。

FruitFactory 类要变,才能在运行时刻提供不同的西瓜。
工厂方法要产生不同的西瓜,就需要客户代码提供不同的type参数
2006-07-25 09:57 | jzhang

# 冰雪晓寒

:),悟性很高啊
2006-07-25 09:58 | jzhang

# re: 抽象工厂模式的好处-to 晓寒

其实这个抽象工厂就是个横行和纵向的矩阵,横向是产品风格族,纵向是产品族。 两个方向都有可能变化, 所以对两个方向都封装,这个也是GOF提出的封装变化点的具体应用。 而切还有别的好处,在我的blog 里已经回复了!
2006-07-25 10:32 | fastzhao的冲洗店

# re: 抽象工厂模式的好处-to 晓寒

非常感谢你们二位。 :)
2006-07-25 11:01 | 晓寒

# re: 抽象工厂模式的好处-to 晓寒

jzhang你描述的只是工厂, 不是抽象工厂. 
工厂只是产品的抽象.
抽象工厂是工厂自身的抽象.

如晓寒的例子则是:
class Fruit;
class AppleFactory;
class BananaFactory; // 香蕉工厂

class FruitCompany //水果公司(以地方为抽象)

    virtual AppleFactory AppleFactory(type) =0;
    virtual BananaFactory BananaFactory(type) =0;
};

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

新疆水果公司的描述
class XJApple: Fruit;
class XJGigApple: Fruit;
class XJAppleFactory: AppleFactory{
      Fruit create(type){return type?XJApple():XJGigApple();}
};
class XJBanana: BananaFactory;
class XJFruitCompany : public FruitCompany {
      virtual AppleFactory AppleFactory(type) {
                    return XJAppleFactory(type);
       }
      .....
};
2006-07-25 11:10 | hpho

# to hpho,抽象工厂其实就是对工厂进行抽象,你说的对

在我的原贴中,CFactory就是抽象基类。
具体的可能有CFactory_Basis或者CFactory_Advance
抽象工厂本身又是通过工厂方法创建的。

另外涉及模式的时候我觉得最好不要贴太多代码,看着很晕 ,赫赫。
2006-07-25 11:19 | jzhang

# re: 抽象工厂模式的好处-to 晓寒

C++因为没有办法根据类型信息(string)来在运行期创造实例出来,所以只有自己手写new,放在工厂里面。

Java里面自从有了Spring framework后,这种手工的工厂就很少使用了。
2006-07-25 11:48 | 小明

# re: 抽象工厂模式的好处-to 晓寒

难得一见的好文及其讨论!
2006-08-03 08:57 | flyingxu

# 抽象工厂模式的好处[TrackBack]

抽象工厂模式的好处
冷剑魂引用了该文章,地址:http://blog.csdn.net/guo_wangwei/archive/2006/09/27/1293065.aspx
2006-09-27 11:34 | 冷剑魂
标题  
姓名  
主页
验证码 *
内容   
  登录  使用高级评论  Top
[使用Ctrl+Enter键可以直接提交]