1、问题背景
1、同一个父类下,产生了太多的子类,使用及处理很麻烦。
为了提高内聚(Cohesion)和松耦合(Coupling),我们经常会抽象出一些类的公共接口以形成抽象基类或者接口。这样我们可以通过声明一个指向基类的指针来指向实际的子类实现,达到了多态的目的。这里很容易出现的一个问题:很多的子类继承自抽象基类,我们不得不在每次要用到子类的地方就编写诸如new ×××的代码。这里带来两个问题1)客户程序员必须知道实际子类的名称(当系统复杂后,命名将是一个很不好处理的问题,为了处理可能的名字冲突,有的命名可能并不是具有很好的可读性和可记忆性,就姑且不论不同程序员千奇百怪的个人偏好了);2)程序的扩展性和维护变得越来越困难。
2、父类中并不知道具体要实例化哪一个具体的子类。
这里的意思为:假设我们在类A中要使用到类B,B是一个抽象父类,在A中并不知道具体要实例化那一个B的子类,但是在类A的子类C中是可以知道的。在A中我们没有办法直接使用类似于new ×××的语句,因为根本就不知道×××是什么。
2、模式示意图
![13095c42a091590f58055bc370088323.png](https://img-blog.csdnimg.cn/img_convert/13095c42a091590f58055bc370088323.png)
工厂方法模式示意图
图中关键Factory模式的应用并不是只是为了封装对象的创建,而是要把对象的创建放到子类中实现:Factory中只是提供了对象创建的接口,其实现将放在Factory的子类ConcreteFactory中进行。
3、代码实现
代码实现如下:
//
//Product.h
//
#ifndef _PRODUCT_H_
#define _PRODUCT_H_
class Product
{
public:
virtual ~Product() = 0;
public:
virtual void fnOperation() = 0;
protected:
Product();
private:
};
class ConcreteProduct:public Product
{
public:
~ConcreteProduct();
ConcreteProduct();
public:
virtual void fnOperation();
protected:
private:
};
#endif //#ifndef _PRODUCT_H_
//
//Product.cpp
//
#include "Product.h"
#include
using namespace std;
Product::Product()
{
}
Product::~Product()
{
}
ConcreteProduct::ConcreteProduct()
{
cout<
}
ConcreteProduct::~ConcreteProduct()
{
}
void ConcreteProduct::fnOperation()
{
cout<
}
//
//Factory.h
//
#ifndef _FACTORY_H_
#define _FACTORY_H_
#include "Product.h"
class Factory
{
public:
virtual ~Factory() = 0;
public:
virtual Product* fnCreateProduct() = 0;
protected:
Factory();
private:
};
class ConcreteFactory:public Factory
{
public:
~ConcreteFactory();
ConcreteFactory();
public:
Product* fnCreateProduct();
protected:
private:
};
#endif //#ifndef _FACTORY_H_
//
//Factory.cpp
//
#include "Factory.h"
#include
using namespace std;
Factory::Factory()
{
}
Factory::~Factory()
{
}
ConcreteFactory::ConcreteFactory()
{
cout<
}
ConcreteFactory::~ConcreteFactory()
{
}
Product* ConcreteFactory::fnCreateProduct()
{
return new ConcreteProduct();
}
//
//main.cpp
//
#include "Factory.h"
#include "Product.h"
#include
using namespace std;
void main()
{
Factory* pFactory = new ConcreteFactory();
Product* pProduct = pFactory->fnCreateProduct();
pProduct->fnOperation();
if (NULL != pProduct)
{
delete pProduct;
pProduct = NULL;
}
if (NULL != pFactory)
{
delete pFactory;
pFactory = NULL;
}
}
运行结果如下:
![83da9924e6d2953af693f413b4445333.png](https://img-blog.csdnimg.cn/img_convert/83da9924e6d2953af693f413b4445333.png)
4、总结与讨论
1、总结
Factory模式的功能特点:
1)、定义创建对象的接口,封装了对象的创建。
2)、使得具体化类的工作延迟到了子类中。
3)、Factory模式局限于一类工厂(即:Product是一类,其所有的Product子类有一个共同的基类)。
2、讨论
问题:在Factory类中,如果为每一个ConcreteProduct类的实例化提供一个函数体,那么我们可能不得不在系统中添加了一个方法来处理这个新建的ConcreteProduct,这样Factory的接口永远就不可能封闭(Close)。
措施:在实现中我们可以采用参数化工厂方法,即给工厂方法fnCreateProduct()传递一个参数用以决定是哪一个ConcreteProduct。