1、动机
在软件系统中,经常面临着创建对象的工作。由于需求的变化,需要创建的对象的具体类型经常变化
如何应对这种变化,如何绕过常规的对象创建方法(new),提供一种“封装机制”来避免客户程序和这种“具体对象创建工作”的紧耦合?
2、定义
定义一个用于创建对象的接口,让子类决定实例化哪一个类。Factory Method 使得一个类的实例化延迟(目的:解耦;手段:抽象方法)到子类
3、结构图
4、代码实现:
// FactoryPattern.hpp
#ifndef FACTORYPATTERN_HPP
#define FACTORYPATTERN_HPP
#include <iostream>
#include <memory>
// 产品基类
class CProduct {
public:
virtual ~CProduct() {}
virtual void mvOperation() = 0;
};
// 具体的产品1
class CConcreteProduct1 : public CProduct {
public:
virtual ~CConcreteProduct1() {}
virtual void mvOperation() {
std::cout << __FUNCTION__ << std::endl;
}
};
// 具体的产品2
class CConcreteProduct2 : public CProduct {
public:
virtual ~CConcreteProduct2() {}
virtual void mvOperation() {
std::cout << __FUNCTION__ << std::endl;
}
};
// 产品类型枚举
enum class E_PRODUCT_TYPE {
PRODUCT_1 = 0,
PRODUCT_2
// ... 可扩展
};
// 工厂类
class CFactory {
public:
virtual ~CFactory() {}
virtual CProduct* mopCreateProduct(E_PRODUCT_TYPE) = 0;
};
// 具体的工厂
class CConcreteFactory : public CFactory {
public:
virtual ~CConcreteFactory() {}
virtual CProduct* mopCreateProduct(E_PRODUCT_TYPE eProductType) {
CProduct* op_create_product = nullptr;
// 创建产品
switch (eProductType) {
case E_PRODUCT_TYPE::PRODUCT_1: {
op_create_product = new CConcreteProduct1;
std::cout << "Create Concrete Product1" << std::endl;
break;
}
case E_PRODUCT_TYPE::PRODUCT_2: {
op_create_product = new CConcreteProduct2;
std::cout << "Create Concrete Product2" << std::endl;
break;
}
// ... 可扩展
default: {
break;
}
}
return op_create_product;
}
};
// 测试代码
void mvTest() {
// 创建工厂
CConcreteFactory* op_concrete_factory = new CConcreteFactory;
std::unique_ptr<CConcreteFactory> uq1(op_concrete_factory);
// 创建产品1
CProduct* op_product1 = op_concrete_factory->mopCreateProduct(E_PRODUCT_TYPE::PRODUCT_1);
std::unique_ptr<CProduct> uq2(op_product1);
op_product1->mvOperation();
//创建产品2
CProduct* op_product2 = op_concrete_factory->mopCreateProduct(E_PRODUCT_TYPE::PRODUCT_2);
std::unique_ptr<CProduct> uq3(op_product2);
op_product2->mvOperation();
}
#endif
5、要点总结
Factory Method 模式用于隔离类对象的使用者和具体类型之间的耦合关系。面对一个经常变化的具体类型,紧耦合关系(new)会导致软件的脆弱
Factory Method 模式通过面向对象的手法(多态),将具体对象的创建工作延迟到子类,从而实现一种扩展(而非更改)的策略,较好地解决了这种紧耦合关系
Factory Method 模式解决“单个对象” 的需求变化,缺点在于要求 创建方法/参数 相同