23种设计模式之一(创建型模式)Factory模式 http://blog.csdn.net/taiyang1987912/article/details/43148913


分类: C++23种设计模式   245人阅读  评论(0)  收藏  举报

目录(?)[+]

一、简介

        Factory 模式是为了解决两类问题:

1、Factory封装对象的创建

        第一种问题是为了提高内聚(Cohesion)和松耦合(Coupling),我们经常会抽象出一些类的公共接口以形成抽象基类或者接口。这样我们可以通过声明一个指向基类的指针来指向实际的子类实现,达到了多态的目的。这里很容易出现的问题是 n 多的Product的子类继承自抽象基类Product,不得不在每次要用到子类的地方就编写诸如 new ConcreteProduct的代码,带来的麻烦即是:(1)客户程序员必须知道实际子类的名称如ConcreteProduct1、ConcreteProduct2等,当系统复杂后,命名将是一个很不好处理的问题(2)程序的扩展性和维护变得越来越困难,必须保存每一个对象的指针。

         为了解决上述问题,我们经常就是使用Factory模式声明一个创建对象的接口,并封装了对象的创建过程。Factory 这里类似于一个真正意义上的Factory工厂(生产对象)。如下图所示:


在工厂中即可使用:

[html]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. Product *ConcreteFactory::CreateProduct(int number)  
  2. {  
  3.    switch(number) {  
  4.        case 1:  
  5.           return new ConcreteProduct1();   
  6.        break;  
  7.        case 2:  
  8.            return new ConcreteProduct2();   
  9.        break;  
  10.        case 3:  
  11.            return new ConcreteProduct3();   
  12.        break;  
  13.    }        
  14. }  

2、Factory具体化类延迟到子类

        第二种问题是在父类Factory中并不知道具体要实例化哪一个具体的子类,比如Factory类中要使用类Product(抽象父类),但Factory中并不知道具体要实例化ConcreteProduct1还是ConcreteProduct3,但在Factory类的子类ConcreteFactory中是可以知道的,故Factory类将具体化类的工作延迟到了子类ConcreteFactory中,使用newConcreteProduct1或new ConcreteProduct3。


        该设计与第一种的区别在于并不是只是为了封装类Product的子类对象的创建,而是要把对象的创建延迟到子类ConcreteFactory中实现,因为有时只有子类中可以决定到底实例化哪一个类。

[html]  view plain copy
  1. Product *ConcreteFactory::CreateProduct()  //创建操作  
  2. {  
  3.     if (_flag == 1) {  
  4.         return new ConcreteProduct1();     //子类中决定要实例化哪一个类  
  5.     }  
  6.     else if (_flag == 3){  
  7.         return new ConcreteProduct3();  
  8.     }  
  9. }  

二、详解

1、代码实现

(仅实现第二种功能代码,完整代码已上传到csdn)

(1)代码product.h:

[html]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. #ifndef _PRODUCT_H_  
  2. #define _PRODUCT_H_  
  3.   
  4. class Product  
  5. {  
  6.     public:  
  7.         virtual ~Product() = 0;  
  8.     protected:  
  9.         Product();  
  10.     private:  
  11. };  
  12.   
  13. class ConcreteProduct1 : public Product  
  14. {  
  15.     public:  
  16.         ~ConcreteProduct1();  
  17.         ConcreteProduct1();  
  18.     protected:    
  19.     private:   
  20. };  
  21. class ConcreteProduct3 : public Product  
  22. {  
  23.     public:  
  24.         ~ConcreteProduct3();  
  25.         ConcreteProduct3();  
  26.     protected:    
  27.     private:   
  28. };  
  29. #endif  
(2)代码product.cpp:

[html]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. #include "product.h"  
  2. #include<iostream>  
  3. using namespace std;  
  4.   
  5. Product::Product()  
  6. {  
  7.     cout<<"Product constructor"<<endl;  
  8. }  
  9.   
  10. Product::~Product()  
  11. {  
  12.     cout<<"Product destructor"<<endl;  
  13. }  
  14.   
  15. ConcreteProduct1::ConcreteProduct1()  
  16. {  
  17.     cout<<"ConcreteProduct1 constructor"<<endl;  
  18. }  
  19.   
  20. ConcreteProduct1::~ConcreteProduct1()  
  21. {  
  22.     cout<<"ConcreteProduct1 destructor"<<endl;  
  23. }  
  24.   
  25. ConcreteProduct3::ConcreteProduct3()  
  26. {  
  27.     cout<<"ConcreteProduct3 constructor"<<endl;  
  28. }  
  29.   
  30. ConcreteProduct3::~ConcreteProduct3()  
  31. {  
  32.     cout<<"ConcreteProduct3 destructor"<<endl;  
  33. }  
(3)代码factory.h:

[html]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. #ifndef _FACTORY_H_  
  2. #define _FACTORY_H_  
  3.   
  4. class Product;  
  5. class Factory  
  6. {  
  7.     public:  
  8.         virtual ~Factory() = 0;  
  9.         virtual Product *CreateProduct() = 0;  
  10.         void setFactoryMethod(int flag);  
  11.     protected:  
  12.         Factory();  
  13.         int _flag;  
  14.     private:  
  15. };  
  16.   
  17. class ConcreteFactory : public Factory  
  18. {  
  19.     public:  
  20.         ~ConcreteFactory();  
  21.         ConcreteFactory();  
  22.         virtual Product *CreateProduct();  
  23.     protected:  
  24.     private:  
  25. };  
  26.   
  27. #endif  
(4)代码factory.cpp:
[html]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. #include "product.h"  
  2. #include "factory.h"  
  3. #include <iostream>  
  4. using namespace std;  
  5. Factory::Factory()  
  6.     :_flag(0)  
  7. {  
  8. }  
  9.   
  10. Factory::~Factory()  
  11. {  
  12. }  
  13.   
  14. void Factory::setFactoryMethod(int flag)  
  15. {  
  16.     _flag = flag;  
  17. }  
  18.   
  19. ConcreteFactory::ConcreteFactory()  
  20. {  
  21.     cout<<"---ConcreteFactory constructor"<<endl;  
  22. }  
  23.   
  24. ConcreteFactory::~ConcreteFactory()  
  25. {  
  26.     cout<<"---ConcreteFactory destructor"<<endl;  
  27. }  
  28.   
  29. Product *ConcreteFactory::CreateProduct()  //创建操作  
  30. {  
  31.     if (_flag == 1) {  
  32.         return new ConcreteProduct1();     //子类中决定要实例化哪一个类  
  33.     }  
  34.     else if (_flag == 3){  
  35.         return new ConcreteProduct3();  
  36.     }  
  37. }  
(5)代码main.cpp:
[html]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. #include "factory.h"  
  2. #include "product.h"  
  3. #include <iostream>  
  4. using namespace std;  
  5.   
  6. int main()  
  7. {  
  8.     Factory *fac = new ConcreteFactory();  
  9.   
  10.     //ConcreteFactory延时通过决定参数决定到底创建具体哪一个Product的子类  
  11.     fac->setFactoryMethod(3);  
  12.     Product *pro = fac->CreateProduct();  
  13.       
  14.     if (pro) {  
  15.         delete pro;  
  16.         pro = NULL;  
  17.     }  
  18.     if (fac) {  
  19.         delete fac;  
  20.         fac = NULL;  
  21.     }  
  22.     return 0;  
  23. }  
(6)makefile文件:
[html]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. CFLAGS = -g  
  2. DEFINED = #-D _VERSION  
  3. LIBS =   
  4. CC = g++  
  5. INCLUDES = -I./  
  6. OBJSmain.o factory.o product.o  
  7. TARGETmain  
  8. all:$(TARGET)  
  9.   
  10. $(TARGET):$(OBJS)  
  11.     $(CC) $(CFLAGS) -o $@ $(OBJS)  
  12.   
  13. .SUFFIXES:.o .h  
  14. .SUFFIXES:.cpp .o  
  15. .cpp.o:  
  16.     $(CC) $(DEFINED) -c $(CFLAGS) -o $@ $<  
  17.   
  18. ok:  
  19.     ./$(TARGET)  
  20. clean:  
  21.     rm -f $(OBJS) $(TARGET) core *.log  

2、运行结果

(centos6.3系统中运行结果:)

三、总结

(1)Factory 模式在实际开发中应用非常广泛,面向对象的系统经常面临着对象创建问题:要创建的类实在是太多了,而 Factory 提供的创建对象的接口封装(第一个功能),以及其将类的实例化推迟到子类(第二个功能)都部分地解决了实际问题。

(2)在实现中通过参数化工厂方法fac->setFactoryMethod(3)决定是创建具体哪一个具体的Product的子类是非常有用的。

(3)Factory 模式带来的问题:如果为每一个具体的ConcreteProduct类的实例化提供一个函数体,那么我们可能不得不在系统中添加了一个方法来处理这个新建的 ConcreteProduct,这样 Factory 的接口永远就不肯能封闭(Close)。当然我们可以通过创建一个 Factory 的子类来通过多态实现这一点,但是这也是以新建一个类作为代价的。虽然Factory 模式对于对象的创建给予开发人员提供了很好的实现策略,但是Factory 模式仅仅局限于一类类(就是说 Product 是一类,有一个共同的基类),如果我们要为不同类的类提供一个对象创建的接口,那就要用 AbstractFactory 了。

(4)源码已经打包上传到csdn上可登录下载(http://download.csdn.net/detail/taiyang1987912/8401713)。  

版权声明:本文为博主原创文章,未经博主允许不得转载。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值