Factory模式是创建对象的用的。
在面向对象语言设计程序时,经常遇到以下2个问题:
- 为了提高内聚和松耦合,经常抽象出类的一些公共接口形成抽象基类或接口。这样在使用时可以通过基类的之后怎或引用调用子类,实现多态。这样在需要创建子类的时就new Class,这样创建子类。由此带来两个问题1、客户程序员必须知道实际子类的名称(因为系统复杂后,为了处理可能冲突的名字,类的命名可能不会那么好记)。2、程序的扩展和维护变得越来越难。
- 在父类中不知道实例化哪个子类。例如在class A中使用到class B,B是一个abstract class,A中不知道要实例化B的哪个子类;但class A的derived class D知道。所以在A中无法使用类似new Class的语句,因为不知道Class是什么。
这两个问题引出了Factory模式的两个最重要的功能:
- 1、定义创建对象的接口,封装对象的创建。
- 2、使得具体化类的工作延迟到了子类中。
工厂模式Factory Pattern
工厂模式解决了第一个问题,封装对象的创建过程。Factory结构有两种,第一种如下:
第二种结构如下:
两种Factory模式的结构原理相同,只是第二种中Factory只是提供了对象创建的接口,将接口的实现放在了Factory的子类ConcreteFactory中。
实现
使用C++实现第二种Factory模式,将定义放在.h文件,实现放在.cpp文件。
//Product.h文件
#ifndef _PRODUCT_H_
#define _PRODUCT_H_
class Product
{
public:
virtual ~Product()=0;
protected:
Product();
private:
};
class ConcreteProduct: public Product
{
public:
~ConcreteProduct();
ConcreteProduct();
protected:
private:
};
#endif
//Product.cpp文件
#include"Product.h"
#include<iostream>
Product::Product()
{
}
Product::~Product()
{
}
ConcreteProduct::ConcreteProduct()
{
std::cout<<"ConcreteProduct"<<std::endl;
}
ConcreteProduct::~ConcreteProduct()
{
}
//Factory.h文件
#ifndef _FACTORY_H_
#define _FACTORY_H_
class Product;//forward declaration
class Factory
{
public:
virtual ~Factory()=0;
virtual Product* CreateProduct()=0;
protected:
private:
};
class ConcreteFactory: public Factory
{
public:
ConcreteFactory();
~ConcreteFactory();
Product* CreateProduct();
};
#endif
//Factory.cpp文件
#include"Product.h"
#include"Factory.h"
#include<iostream>
Factory::~Factory()
{
}
ConcreteFactory::ConcreteFactory()
{
std::cout<<"ConcreteFactory"<<std::endl;
}
ConcreteFactory::~ConcreteFactory()
{
}
Product* ConcreteFactory::CreateProduct()
{
return new ConcreteProduct();
}
//main函数所在文件
#include"Factory.h"
#include"Product.h"
#include<iostream>
int main()
{
Factory* fac=new ConcreteFactory();
Product* p=fac->CreateProduct();
return 0;
}
使用Factory模式,容易带来以下两个问题:
- 1、如果为每一个具体的ConcreteProduct类都提供一个实例化函数,就必须在Factory类中添加一个方法来处理新建的ConcreteProduct,这样Factory接口就不能封闭。可以通过Factory子类多态实现,但这是以新建一个类作为代价的。
- 2、可以通过参数工厂实现,即给FactoryMethod添加一个参数来决定创建哪一个具体的Product。可以通过模板避免1中过多创建子类,即将Product类作为模板参数。
AbstractFactory模式
AbstractFactory模式是用来创建一组相关或相互依赖的对象,这一组对象可能有多个父类。Factory模式是用来创建一类对象,这些对象都有共同的父类。下图是AbstractFactory的类图模型,一个抽象工厂有两个实例工厂,每个实例工厂用来创建一组对象。有两个抽象Product,它们都有派生的实例Product。
实现
下面是代码实现
//Product.h
#ifndef _PRODUCT_H_
#define _PRODUCT_H_
class AbstractProductA{
public:
AbstractProductA();
virtual ~AbstractProductA();
};
class AbstractProductB{
public:
AbstractProductB();
virtual ~AbstractProductB();
};
class ProductA1: public AbstractProductA{
public:
ProductA1();
~ProductA1();
};
class ProductA2: public AbstractProductA{
public:
ProductA2();
~ProductA2();
};
class ProductB1: public AbstractProductB{
public:
ProductB1();
~ProductB1();
};
class ProductB2: public AbstractProductB{
public:
ProductB2();
~ProductB2();
};
#endif
//Product.cpp
#include"Product.h"
#include<iostream>
AbstractProductA::AbstractProductA()
{}
AbstractProductA::~AbstractProductA()
{}
AbstractProductB::AbstractProductB()
{}
AbstractProductB::~AbstractProductB()
{}
ProductA1::ProductA1()
{
std::cout<<"Product A1"<<std::endl;
}
ProductA1::~ProductA1()
{}
ProductA2::ProductA2()
{
std::cout<<"Product A2"<<std::endl;
}
ProductA2::~ProductA2()
{}
ProductB1::ProductB1()
{
std::cout<<"Product B1"<<std::endl;
}
ProductB1::~ProductB1()
{}
ProductB2::ProductB2()
{
std::cout<<"Product B2"<<std::endl;
}
ProductB2::~ProductB2()
{}
//AbstractFactory.h
#ifndef _ABSTRACTFACTORY_H_
#define _ABSTRACTFACTORY_H_
class AbstractProductA;
class AbstractProductB;
class AbstractFactory{
public:
AbstractFactory();
virtual ~AbstractFactory();
virtual AbstractProductA* CreateProductA()=0;
virtual AbstractProductB* CreateProductB()=0;
};
class ConcreteFactory1:public AbstractFactory{
public:
ConcreteFactory1();
~ConcreteFactory1();
AbstractProductA* CreateProductA();
AbstractProductB* CreateProductB();
};
class ConcreteFactory2:public AbstractFactory{
public:
ConcreteFactory2();
~ConcreteFactory2();
AbstractProductA* CreateProductA();
AbstractProductB* CreateProductB();
};
#endif
//AbstractFactory.cpp
#include"AbstractFactory.h"
#include"Product.h"
#include<iostream>
AbstractFactory::AbstractFactory()
{}
AbstractFactory::~AbstractFactory()
{}
ConcreteFactory1::ConcreteFactory1()
{}
ConcreteFactory1::~ConcreteFactory1()
{}
AbstractProductA* ConcreteFactory1::CreateProductA()
{
std::cout<<"CreateProductA1"<<std::endl;
return new ProductA1();
}
AbstractProductB* ConcreteFactory1::CreateProductB()
{
std::cout<<"CreateProductB1"<<std::endl;
return new ProductB1();
}
ConcreteFactory2::ConcreteFactory2()
{}
ConcreteFactory2::~ConcreteFactory2()
{}
AbstractProductA* ConcreteFactory2::CreateProductA()
{
std::cout<<"CreateProductA2"<<std::endl;
return new ProductA2();
}
AbstractProductB* ConcreteFactory2::CreateProductB()
{
std::cout<<"CreateProductB2"<<std::endl;
return new ProductB2();
}
//main.cpp
#include"AbstractFactory.h"
int main()
{
AbstractFactory* CF1=new ConcreteFactory1();
CF1->CreateProductA();
CF1->CreateProductB();
AbstractFactory* CF2=new ConcreteFactory2();
CF2->CreateProductA();
CF2->CreateProductB();
return 0;
}