工厂模式(C/C++实现理解)

       (一) 用C实现产品,采用模块化设计,产品被划分为不同模块单元。逻辑功能相同部分采用函数进行封装,模块与模块之间一般会调用API接口交互处理。模块(B,C,D...)会同时调用A接口void InfA0(int).

#include <stdio.h>
#include <string.h>


#define ModuleBInputPara 1;
#define ModuleCInputPara 2;

void InfA0(int number)
{
    int a = number;

    switch(a)
    {
          case 1:
             printf("\r\n module B\n");
             break;
          case 2:
             printf("\r\n module C\n");
             break;
          default:
             break;
    }

    return;
}

void ModuleB(void)
{
    InfA0(ModuleBInputPara);
    return;
}
void ModuleC(void)
{
    InfA0(ModuleCInputPara );
    return;
}

int main()
{
    ModuleB();
    ModuleC();
}

如果B需要输出C,C需要输出B,怎么处理。第一步是修改配置参数ModuleBInputPara与 ModuleCInputPara ,第二步是修改接口InfA0,增加两条case项。 (简单工厂模式)

【优点】B,C模块与A模块偶合小。B与C不需要修改代码。实现前提是将B,C 相关部分抽象成接口(InfA0).

【缺点】InfA0管理更多分支。

疑问 如果B,C模块中调用接口InfA0命名需要改变(如InfA1),例如系统需要移植到新的硬件或软件平台。B与C则需要修改代码,尽管这些接口的入参,出参,返回值相同。

怎么去解决此问题呢?可用指向函数的指针代替接口。(类似工厂方法模式)

 void (pFun *)(int);


void ModuleB(void)
{
    pFun (ModuleBInputPara);
    return;
}
void ModuleC(void)
{
    pFun (ModuleCInputPara );
    return;
}


int main()

{

    pFun =    InfA0;

    ModuleB();
    ModuleC();

}   

【优点】B,C与A尽一步解耦

【缺点】如果pFun在没初始化前使用会出现野指针。

疑问如果B,C需要调用一系列A提供接口,怎么办?可采用函数指针结构体 (抽象工厂方法模式)

(二)上面A类似工厂,B与C类似客户。同时print 动作抽象到具体产品



图1:简单工厂模式

客户(B/C)依赖A接口类,如果客户直接依赖产品1或产品2,如果客户有需要变更时,B/C需要修改大量实体代码。耦合性较差。

1 #include <iostream>

  2 using namespace std;
  3
  4 class product
  5 {
  6     public:
  7     virtual void produce() = 0;
  8 };
  9
 10 class product1:public product
 11 {
 12     public:
 13         void produce()
 14         {
 15             cout<<"product1"<<endl;
 16         }
 17 };
 18
 19 class product2:public product
 20 {
 21     public:
 22         void produce()
 23         {
 24             cout<<"product2"<<endl;
 25         }
 26 };
 27
 28 class factory
 29 {
 30     public:
 31        product* createproduct(int num)
 32        {
 33               switch(num)
 34               {
 35                   case 1:
 36                       return new product1;
 37                       break;
 38                   case 2:
 39                       return new product2;
 40                       break;
 41                   default:
 42                       break;
 43               }
 44        }
 45 };
 46
 47 int main()       

 48 {

 49     factory fact;
 50     product *prod;
 51     prod = fact.createproduct(2);
 52     prod->produce();
 53     return 0;
 54   }

如果用户需要更改产品的类型(类似(一)中接口变化啦)。此时如果用户已生产了多个产品,每个产品都要更换。(fact.createproduct(2-->1).工厂方法可解决此问题。

修改factory

class factory
 {
      public:
         virtual product* createproduct()  =  0;      
  };

class factory1:public factory

{

    public:    

        product *createproduct()

        {

             return new product1;

         }

}

class factory2:public factory

{

    public:      

        product *createproduct()

        {

             return new product2;

         }

}

 int main()       

 {

    factory *fact = new factory1();  // 更改时,仅需要修改为 new factory2()
    product *prod;
    prod = fact .createproduct();

    prod = fact .createproduct();

    prod->produce();
   return 0;
}



图2, 工厂方法类图

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值