设计模式之工厂模式
设计模式之工厂模式
一.普通工厂模式
为了提高内聚和松聚合,抽象出一些类的公共接口以形成抽象基类,然后声明基类指针指向派生类对象,以达到多态的目的。当有很多派生类继承自该抽象基类时,需要写很多new
,而且客户必须知道派生类的名称才能生成该对象,如果不知道要实例化哪一个具体的派生类,也就无法使用new
。
工厂模式的两大功能:
- 定义创建对象的接口,封装了对象的创建;
- 将具体化类的工作延迟到了派生类中;
结构示意图如下:
完整代码
//Product.h
#ifndef _PRODUCT_H_
#define _PRODUCT_H_
#include <iostream>
class Product {
public:
virtual ~Product() = 0;
protected:
Product() {} //屏蔽构造函数
};
class ConcreteProduct : public Product {
public:
virtual ~ConcreteProduct() {}
ConcreteProduct() {
std::cout << "ConcreteProduct..." << std::endl;
}
};
Product::~Product() {}
#endif //_PRODUCT_H_
//Factory.h
#ifndef _FACTORY_H_
#define _FACTORY_H_
#include "Product.h"
//class Product;
class Factory {
public:
virtual ~Factory() = 0;
virtual Product* CreateProduct() = 0;
protected:
Factory() {}
};
class ConcreteFactory : public Factory {
public:
virtual ~ConcreteFactory() {}
ConcreteFactory() {
std::cout << "ConcreteFactory..." << std::endl;
}
Product* CreateProduct() {
return new ConcreteProduct();
}
};
Factory::~Factory(){}
#endif // _FACTORY_H_
//Factory-test.cpp
#include "Factory.h"
using namespace std;
int main() {
Factory *fac = new ConcreteFactory();
Product *p = fac->CreateProduct();
return 0;
}
运行结果:
分析一下代码:
类Product即抽象出来的基类,类ConcreteProduct是其派生类是真实需要创造的产品,其构造函数的动作即为生成产品实例;类Factory中的函数CreateProduct()
是一个纯虚函数(纯接口)返回的是Product*,在其派生类ConcreteFactory中,则实现了这个接口,这个接口封装了对象的创建。最后在Factory-test.cpp中就可以使用多态来创建ConcreteProduct对象。要创造不同的产品,只需要将类Factory中的CreateProduct()
传递一个参数,这个参数来决定要创建哪一个具体的Product。
工厂模式仅仅适用于多个类继承自一个公共的基类,如果需要为不同的类的子类创建对象,就要使用抽象工厂模式了。
二.抽象工厂模式
抽象工厂模式和工厂模式类似,其结构示意图如下:
完整的代码实现:
//Product.h
#ifndef _PRODUCT_H_
#define _PRODUCT_H_
#include <iostream>
class AbstractProductA {
public:
virtual ~AbstractProductA() = 0;
protected:
AbstractProductA() {} //屏蔽构造函数
};
AbstractProductA::~AbstractProductA() {}
class AbstractProductB {
public:
virtual ~AbstractProductB() = 0;
protected:
AbstractProductB() {} //屏蔽构造函数
};
AbstractProductB::~AbstractProductB() {}
class ProductA1 : public AbstractProductA {
public:
virtual ~ProductA1() {}
ProductA1() {
std::cout << "ProductA1..." << std::endl;
}
};
class ProductA2 : public AbstractProductA {
public:
virtual ~ProductA2() {}
ProductA2() {
std::cout << "ProductA2..." << std::endl;
}
};
class ProductB1 : public AbstractProductB {
public:
virtual ~ProductB1() {}
ProductB1() {
std::cout << "ProductB1..." << std::endl;
}
};
class ProductB2 : public AbstractProductB {
public:
virtual ~ProductB2() {}
ProductB2() {
std::cout << "ProductB2..." << std::endl;
}
};
#endif //_PRODUCT_H_
//AbstractFactory.h
#ifndef _ABSTRACTFACTORY_H_
#define _ABSTRACTFACTORY_H_
#include "Product.h"
class AbstractFactory {
public:
virtual ~AbstractFactory() = 0;
virtual AbstractProductA* CreateProductA() = 0;
virtual AbstractProductB* CreateProductB() = 0;
protected:
AbstractFactory() {}
};
AbstractFactory::~AbstractFactory() {}
AbstractProductA* AbstractFactory::CreateProductA() {}
AbstractProductB* AbstractFactory::CreateProductB() {}
class ConcreteFactory1 : public AbstractFactory {
public:
~ConcreteFactory1();
ConcreteFactory1() {
std::cout << "ConcreteFactory1..." << std::endl;
}
AbstractProductA* CreateProductA() {
return new ProductA1();
}
AbstractProductB* CreateProductB() {
return new ProductB1();
}
};
ConcreteFactory1::~ConcreteFactory1() {}
class ConcreteFactory2 : public AbstractFactory {
public:
virtual ~ConcreteFactory2();
ConcreteFactory2() {
std::cout << "ConcreteFactory2..." << std::endl;
}
AbstractProductA* CreateProductA() {
return new ProductA2();
}
AbstractProductB* CreateProductB() {
return new ProductB2();
}
};
ConcreteFactory2::~ConcreteFactory2() {}
#endif // _ABSTRACTFACTORY_H_
//main.cpp
#include "Product.h"
#include "AbstractFactory.h"
using namespace std;
int main() {
AbstractFactory *cf1 = new ConcreteFactory1();
cf1->CreateProductA();
cf1->CreateProductB();
AbstractFactory *cf2 = new ConcreteFactory2();
cf2->CreateProductA();
cf2->CreateProductB();
return 0;
}
输出结果如下:
简单分析:
抽象产品基类AbstractProductA
,AbstractProductB
,四个继承的产品子类ProductA1,ProductA2
,ProductB1,ProductB2
,一个抽象工厂基类AbstractFactory
,以及对应的两个继承的子类ConcreteFactory1, ConcreteFactory2
,通过这两个继承子类中重写了的基类的纯虚方法:CreateProductA,CreateProductB
方法来进行产品类的创建,利用多态,直接使用工厂基类的指针调用该方法即可。
总结:
抽象工厂模式和工厂模式的原理是一样的,都是封装了对象的创建,并且将实例化对象的任务交给了子类,不同点在于:工厂模式只为一类对象提供创建接口或延迟对象的创建到子类,而抽象工厂模式则为一组(多个类)相关或者依赖的对象提供创建接口或延迟对象的创建到子类
主要参考自《设计模式精解-GoF 23种设计模式解析附C++实现源码》作者:K_Eckel, 作者EMAIL:aaa@qq.com
上一篇: 设计模式之工厂模式
下一篇: ensp 三层架构配置