设计模式之创建模式:工厂模式与抽象工厂模式

假如要处理两类数据:男和女(男女考虑问题是不一样的)

最简单的就是定义两个类( Male和Female)(V1.0

/*V1.0*/
class Male{
}
class Female{
}

但是我们发现Male和Female是有共同部分的,所以这时候我们有定义 了Human类,让Male和Female继承Human类(V2.0),这时候改动比较大。目前来说有三个类。

/*V2.0*/
class Human{
}
class Male:public Human{
}
class Female:public Human{
}

然后我们有发现实际上还要考虑肤色,这时候有几种考虑:

1.改Human类,添加有关肤色的内容,但是肤色凭什么比性别的层次高呢?

2.改Male类和Female类,给其中添加与肤色有关的内容,这是肯定有大量代码冗余啊!

3.推倒重来---疯了!

......

其实到这里我们已经会发现路已经走不下去了,随着项目的进行,需要修改的地方越来越多,最终可能导致崩溃!

而且在演进的过程中我们希望添加大于改动,上述的内容希望继承前面的代码,其结果却是越来越乱!

如下改动:

1.肤色有关的内容放到Human类中

2.Male和Female改为 BlackMale,BlackFemale,WhiteMale,WhiteFemale,YellowMale和YellowFemale

至此有7个类,如果还有其他的在添加(类的急剧膨胀!)(V3.0

/*V3.0*/
class Human{
}
class YellowMale:public Human{
}
class YellowFemale:public Human{
}
class BlackMale:public Human{
}
class BlackFemale:public Human{
}
class WhiteMale:public Human{
}
class WhiteFemale:public Human{
}

不过在演进到V3.0的时候,有几个问题:

  • V1.0,V2.0的知识都不能用了
  • 类太多,使用者也不容易记忆

能有种方法减少记忆吗?

有!就是归类!将代码也归类!

使用者只要调用极少的函数,就可以使用对应的类创建对象,所以这时候要做两件事:

1.提供创建对象的统一工具

2.定义使用类统一的界面

考虑创建对象的工具,如下:

/*工厂模式V1.0*/
class Factory{
...
   YellowMale *createYellowMale();
   YellowFemale *createYellowFemale();
...
}

也可以如下改进,使用带参函数:

/*工厂模式v2.0*/
class Factory{
...
  Human *createHuman(string name){
     switch(name){
        case "YellowMale":
            ...
        casse "YellowFemale":
            ...
     }
   }
}

这些都是工厂模式!工厂模式就是为了提供创建对象的统一工具!

能不能再改进一下呢?如果在添加棕色人种呢?这是怎么办呢?

仔细分析一下上述代码,我们发现这六个函数是相关的(这个很关键,如果没有这一点的话我们只能去修改代码了),可以进行归类,或者按照肤色分,或者按照性别分都可以,此处按照肤色分:

/*抽象工厂v1.0*/
class YellowFactory{
...
   YellowMale *createYellowMale();
   YellowFemale *createYellowFemale();
...
}
class BlackFactory{
...
   BlackMale *createBlackMale();
   BlackFemale *createBlackFemale();
...
}
class WhiteFactory{
...
   WhiteMale *createWhiteMale();
   WhiteFemale *createWhiteFemale();
...
}

但是太丑陋了!

  • 3个类的有太多的冗余代码,且记忆的内容太多
  • 类与类之间是有联系的,不能视而不见
  • 如果现在再添加一类人种,比如说棕色呢?

将公共的代码抽取出来,形成这三个类的父类,而父类作为接口:

/*抽象工厂v2.0*/
class Factory{
...
   virtual Male *createMale()=0;
   virtual Female *createFemale()=0;
...
}
class YellowFactory :public Factory{
...
   YellowMale *createMale();
   YellowFemale *createFemale();
...
}
class BlackFactory:public Factory{
...
   BlackMale *createMale();
   BlackFemale *createFemale();
...
}
class WhiteFactory:public Factory{
...
   WhiteMale *createMale();
   WhiteFemale *ceateFemale();
...
}

*请注意抽象工厂V2.0中的Factory类,在设计之初并不知道真正的工厂创建的对象类型,但是知道有那些动作,而下面的具体工厂是知道创建对象的类型的(比如说YellowFactory类是知道要创建的对象类型的)。

另外这种形式扩展也容易,比如要添加棕色人种,那么只要添加棕色人种类和棕色人种工厂即可:

class BrownMale:public Human{
}
class BrownFeMale:public Human{
}
class BrownFactory:public Factory{
...
   BrownMale *createMale();
   BrownFemale *createFemale();
...
}

也许有人会说抽象工厂V2.0版的工厂有4个类,就改成1个类或2个类,不是类更少,更好记吗?比如:

/*1个类实现方案1*/
class Factory{
...
   YellowMale *createYellowMale();
   YellowMale *createYellowFemale();
...
   BlackMale *createBlackMale();
   BlackFemale *createBlackFemale();
...

   WhiteMale *createWhiteMale();
   WhiteFemale *createWhiteFemale();
...
}
/*1个类实现方案2*/
class Factory{
...
  Human *createHuman(string name){
     switch(name){
        case "YellowMale":
            ...
        casse "YellowFemale":
            ...
     }
      
   }
   
}

这实际上前面的工厂模式了,而且如果要有新的类(如BrownMale和BrownFemale)它还要修改!

或是2个类实现:

/*2个类实现*/
class AbstractFactory{
  virtual Male *createMale(string )=0;
  virtual Female *createFemale(string )=0;
}
class ConcreteFactory:public AbstructFactory{
...
   Male *createMale(string name){
     switch(name){
        case "YellowMale":
            ...
        casse "YellowFemale":
            ...
     }
      
   }
   Female *createFemale(string name){
       ...
   }
...
}

2个类的方案在扩展时主要靠修改!(又是它!) ,记住宁添勿改! 且在使用时也是非常不便的:

...
ConcreteFactory fac= new ConcreteFactory();
YellowMale *p1=(YellowMale *)fac->createMale("YellowMale");
...

*本文中采用4个类实现抽象工厂模式,<<设计之禅>>中采用3个类:

class HumanFactory{
...
  Human *createYellowHuman();
  Human *createWhiteHuman();
  Human *createBlackHuman();
...
}
class MaleFactory:public HumanFactory{
...
  YellowMaleHuman *createYellowHuman();
  WhiteMaleHuman *createWhiteHuman();
  BlackMaleHuman *createBlackHuman();
...
}
class FemaleFactory:public HumanFactory{
...
  YellowFemaleHuman *createYellowHuman();
  WhiteFemaleHuman *createWhiteHuman();
  BlackFemaleHuman *createBlackHuman();
...
}

似乎本文的方法扩展性更好些,这只是合并、分类的标准不同而已。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值