一、简介
Factory 模式是为了解决两类问题:
1、Factory封装对象的创建
第一种问题是为了提高内聚(Cohesion)和松耦合(Coupling),我们经常会抽象出一些类的公共接口以形成抽象基类或者接口。这样我们可以通过声明一个指向基类的指针来指向实际的子类实现,达到了多态的目的。这里很容易出现的问题是 n 多的Product的子类继承自抽象基类Product,不得不在每次要用到子类的地方就编写诸如 new ConcreteProduct的代码,带来的麻烦即是:(1)客户程序员必须知道实际子类的名称如ConcreteProduct1、ConcreteProduct2等,当系统复杂后,命名将是一个很不好处理的问题(2)程序的扩展性和维护变得越来越困难,必须保存每一个对象的指针。
为了解决上述问题,我们经常就是使用Factory模式声明一个创建对象的接口,并封装了对象的创建过程。Factory 这里类似于一个真正意义上的Factory工厂(生产对象)。如下图所示:
在工厂中即可使用:
- Product *ConcreteFactory::CreateProduct(int number)
- {
- switch(number) {
- case 1:
- return new ConcreteProduct1();
- break;
- case 2:
- return new ConcreteProduct2();
- break;
- case 3:
- return new ConcreteProduct3();
- break;
- }
- }
2、Factory具体化类延迟到子类
第二种问题是在父类Factory中并不知道具体要实例化哪一个具体的子类,比如Factory类中要使用类Product(抽象父类),但Factory中并不知道具体要实例化ConcreteProduct1还是ConcreteProduct3,但在Factory类的子类ConcreteFactory中是可以知道的,故Factory类将具体化类的工作延迟到了子类ConcreteFactory中,使用newConcreteProduct1或new ConcreteProduct3。
该设计与第一种的区别在于并不是只是为了封装类Product的子类对象的创建,而是要把对象的创建延迟到子类ConcreteFactory中实现,因为有时只有子类中可以决定到底实例化哪一个类。
- Product *ConcreteFactory::CreateProduct() //创建操作
- {
- if (_flag == 1) {
- return new ConcreteProduct1(); //子类中决定要实例化哪一个类
- }
- else if (_flag == 3){
- return new ConcreteProduct3();
- }
- }
二、详解
1、代码实现
(仅实现第二种功能代码,完整代码已上传到csdn)
(1)代码product.h:
- #ifndef _PRODUCT_H_
- #define _PRODUCT_H_
- class Product
- {
- public:
- virtual ~Product() = 0;
- protected:
- Product();
- private:
- };
- class ConcreteProduct1 : public Product
- {
- public:
- ~ConcreteProduct1();
- ConcreteProduct1();
- protected:
- private:
- };
- class ConcreteProduct3 : public Product
- {
- public:
- ~ConcreteProduct3();
- ConcreteProduct3();
- protected:
- private:
- };
- #endif
- #include "product.h"
- #include<iostream>
- using namespace std;
- Product::Product()
- {
- cout<<"Product constructor"<<endl;
- }
- Product::~Product()
- {
- cout<<"Product destructor"<<endl;
- }
- ConcreteProduct1::ConcreteProduct1()
- {
- cout<<"ConcreteProduct1 constructor"<<endl;
- }
- ConcreteProduct1::~ConcreteProduct1()
- {
- cout<<"ConcreteProduct1 destructor"<<endl;
- }
- ConcreteProduct3::ConcreteProduct3()
- {
- cout<<"ConcreteProduct3 constructor"<<endl;
- }
- ConcreteProduct3::~ConcreteProduct3()
- {
- cout<<"ConcreteProduct3 destructor"<<endl;
- }
- #ifndef _FACTORY_H_
- #define _FACTORY_H_
- class Product;
- class Factory
- {
- public:
- virtual ~Factory() = 0;
- virtual Product *CreateProduct() = 0;
- void setFactoryMethod(int flag);
- protected:
- Factory();
- int _flag;
- private:
- };
- class ConcreteFactory : public Factory
- {
- public:
- ~ConcreteFactory();
- ConcreteFactory();
- virtual Product *CreateProduct();
- protected:
- private:
- };
- #endif
- #include "product.h"
- #include "factory.h"
- #include <iostream>
- using namespace std;
- Factory::Factory()
- :_flag(0)
- {
- }
- Factory::~Factory()
- {
- }
- void Factory::setFactoryMethod(int flag)
- {
- _flag = flag;
- }
- ConcreteFactory::ConcreteFactory()
- {
- cout<<"---ConcreteFactory constructor"<<endl;
- }
- ConcreteFactory::~ConcreteFactory()
- {
- cout<<"---ConcreteFactory destructor"<<endl;
- }
- Product *ConcreteFactory::CreateProduct() //创建操作
- {
- if (_flag == 1) {
- return new ConcreteProduct1(); //子类中决定要实例化哪一个类
- }
- else if (_flag == 3){
- return new ConcreteProduct3();
- }
- }
- #include "factory.h"
- #include "product.h"
- #include <iostream>
- using namespace std;
- int main()
- {
- Factory *fac = new ConcreteFactory();
- //ConcreteFactory延时通过决定参数决定到底创建具体哪一个Product的子类
- fac->setFactoryMethod(3);
- Product *pro = fac->CreateProduct();
- if (pro) {
- delete pro;
- pro = NULL;
- }
- if (fac) {
- delete fac;
- fac = NULL;
- }
- return 0;
- }
- CFLAGS = -g
- DEFINED = #-D _VERSION
- LIBS =
- CC = g++
- INCLUDES = -I./
- OBJS= main.o factory.o product.o
- TARGET= main
- all:$(TARGET)
- $(TARGET):$(OBJS)
- $(CC) $(CFLAGS) -o $@ $(OBJS)
- .SUFFIXES:.o .h
- .SUFFIXES:.cpp .o
- .cpp.o:
- $(CC) $(DEFINED) -c $(CFLAGS) -o $@ $<
- ok:
- ./$(TARGET)
- clean:
- 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)。
版权声明:本文为博主原创文章,未经博主允许不得转载。