工厂方法模式
1 概念
工厂方法模式是指一个工厂接口用来声明创建产品对象,具体创建的产品对象由派生类工厂实现,达到一个工厂生产一种产品对象的目的。工厂方法很好地解决了一个工厂进行一种产品的生产,且各个产品又不互相依赖的问题。
2 意图(Intent)
定义了一个创建对象的抽象方法,由子类决定要实例化的类,工厂方法模式将对象的实例化推迟到子类。
3 动机(Motivate)
考虑到这样一个系统,电子产品工厂生产可以生产一个具体的电子产品,如手机、平板等。吐过我们需要新增一个产品,比如智能手表,除了需要新增产品类外,还需要通过修改工厂类代码来实现,这样就违法了开闭原则。我们通过定义一个用于创建对象的接口,让子类决定实例化创建哪一个类。,工厂方法模式使一个类的实例化延迟到其子类。
4 类图结构

5 角色定义
- Product(产品):所有产品的父类,可以是抽象类或接口。
- ConcreteProduct(具体产品):由产品Product派生出的产品子类,可以有多个产品子类。
- Factory(工厂):定义工厂方法的工厂接口,当然也可以是抽象类,它使顶级工厂制造方法抽象化,标准统一化。
- ConcreteFactory(具体工厂):实现了工厂接口的工厂实现类,并决定工厂方法中具体返回哪种产品子类的实例。
6 程序示例
基本工厂方法和产品
产品基类BaseProduct
cpp
class BaseProduct
{
public:
BaseProduct() = default;
virtual ~BaseProduct();
public:
virtual void SomeMethod() = 0;
};
BaseProduct::~BaseProduct()
{
qDebug() << "Destructor BaseProduct";
}
具体产品类ProductA
CPP
class ProductA: public BaseProduct
{
public:
ProductA() = default;
~ProductA() = default;
public:
void SomeMethod() override;
};
void ProductA::SomeMethod()
{
qDebug() << "ProductA SomeMethod";
}
具体产品类ProductB
cpp
class ProductB: public BaseProduct
{
public:
ProductB() = default;
~ProductB() = default;
public:
void SomeMethod() override;
};
void ProductB::SomeMethod()
{
qDebug() << "ProductB SomeMethod";
}
工厂基类BaseFactory,我们抽象的是创建产品的方法
cpp
class BaseFactory
{
public:
BaseFactory() = default;
virtual ~BaseFactory();
public:
virtual BaseProduct* CreateProduct() = 0;
};
BaseFactory::~BaseFactory()
{
qDebug() << "Destructor BaseFactory";
}
具体工厂类FactoryA
cpp
class FactoryA : public BaseFactory
{
public:
FactoryA() = default;
~FactoryA() = default;
public:
BaseProduct* CreateProduct() override;
};
BaseProduct *FactoryA::CreateProduct()
{
return new ProductA();
}
具体工厂类FactoryB
cpp
class FactoryB : public BaseFactory
{
public:
FactoryB() = default;
~FactoryB() = default;
public:
BaseProduct* CreateProduct() override;
};
BaseProduct *FactoryB::CreateProduct()
{
return new ProductB();
}
测试工厂模式程序
cpp
// 非智能指针模式
void TestFactory()
{
BaseFactory* pFactorA = new FactoryA();
BaseProduct* pProductA = pFactorA->CreateProduct();
pProductA->SomeMethod();
delete pFactorA;
delete pProductA;
}
// 智能指针模式
void TestFactory()
{
std::unique_ptr<BaseFactory> upFactorA = std::make_unique<FactoryA>();
std::unique_ptr<BaseProduct> upProductA;
upProductA.reset(upFactorA->CreateProduct());
upProductA->SomeMethod();
}
生产手机和平板的工厂
类的结构图

颜色较浅的为高层、抽象层,相对稳定,也就是我们所谓的很少变化的模块,而颜色较深的为具体层,稳定性相对较差,变化会比较多。
代码示例:
电子产品基类
cpp
/**
* @brief 电子产品基类
*/
class ElectronicProduct
{
public:
ElectronicProduct() = default;
virtual ~ElectronicProduct() = default;
public:
virtual void Show() = 0;
};
手机类
cpp
/**
* @brief 手机类
*/
class PhoneProduct: public ElectronicProduct
{
public:
PhoneProduct() = default;
~PhoneProduct() = default;
public:
void Show() override;
};
void PhoneProduct::Show()
{
qDebug() << "Phone Show";
}
平板类
cpp
/**
* @brief 平板类
*/
class PadProduct: public ElectronicProduct
{
public:
PadProduct() = default;
~PadProduct() = default;
public:
void Show() override;
};
void PadProduct::Show()
{
qDebug() << "Pad Show";
}
工厂接口类,我们抽象的是创建电子产品的方法
cpp
/**
* @brief 工厂接口类
*/
class IFactory
{
public:
IFactory() = default;
virtual ~IFactory() = default;
public:
virtual ElectronicProduct* CreateProduct() = 0;
};
手机工厂类,也是具体工厂的角色
cpp
/**
* @brief 手机工厂类
*/
class PhoneFactory : public IFactory
{
public:
PhoneFactory() = default;
~PhoneFactory() = default;
public:
ElectronicProduct* CreateProduct() override;
};
ElectronicProduct *PhoneFactory::CreateProduct()
{
return new PhoneProduct();
}
平板工厂类,也是具体工厂的角色
cpp
/**
* @brief 平板工厂类
*/
class PadFactory : public IFactory
{
public:
PadFactory() = default;
~PadFactory() = default;
public:
ElectronicProduct* CreateProduct() override;
};
ElectronicProduct* PadFactory::CreateProduct()
{
return new PadProduct();
}
测试函数
cpp
void ClientTest()
{
IFactory* pPhoneFactory = new PhoneFactory();
IFactory* pPadFactory = new PadFactory();
ElectronicProduct* pPhone = pPhoneFactory->CreateProduct();
ElectronicProduct* pPad = pPadFactory->CreateProduct();
pPhone->Show();
pPad->Show();
delete pPhoneFactory;
delete pPadFactory;
delete pPhone;
delete pPad;
}
7 思考小结
工厂方法模式让对象的创建和实现相互独立,它对工厂制造方法进行接口规范化,以允许子类工厂决定具体制造哪类产品的实例,可以达到松耦合的目的;具体的工厂生成具体的产品,方便理解程序的结构,但是缺点也很明显,如果要增加新的产品类,还需要增加对应的新工厂。
怎样记住工厂方法模式的结构,我们只需要记住两个抽象方向,工厂抽象的方向为创建产品,产品抽象的方向为不同产品,工厂抽象类依赖产品抽象类,也就是所谓的高层模块依赖高层模块,而具体的工厂依赖具体的产品,也就是低层模块依赖低层模块,这样达到高层(稳定)和低层(不稳定)的隔离。
8 附录-简单工厂
简单工厂只对产品进行抽象,让工厂对象通过其自身方法中的形参变量决定创建产品的类型。
程序示例
工厂创建产品函数的枚举
cpp
enum E_PRODUCT_TYPE
{
PRODUCT_A,
PRODUCT_B,
PRODUCT_C
};
产品基类
cpp
class BaseProduct
{
public:
BaseProduct() = default;
virtual ~BaseProduct();
public:
virtual void Show() = 0;
};
BaseProduct::~BaseProduct()
{
// ...
}
产品A类
cpp
class ProductA : public BaseProduct
{
public:
ProductA() = default;
~ProductA() = default;
public:
void Show() override;
};
void ProductA::Show()
{
qDebug() << "Show ProductA";
}
产品B类
cpp
class ProductB : public BaseProduct
{
public:
ProductB() = default;
~ProductB() = default;
public:
void Show() override;
};
void ProductB::Show()
{
qDebug() << "Show ProductB";
}
产品C类
cpp
class ProductC : public BaseProduct
{
public:
ProductC() = default;
~ProductC() = default;
public:
void Show() override;
};
void ProductC::Show()
{
qDebug() << "Show ProductC";
}
工厂类部分
cpp
class Factory
{
public:
Factory() = default;
~Factory() = default;
public:
BaseProduct* CreateProduct(E_PRODUCT_TYPE eProductType);
};
BaseProduct* Factory::CreateProduct(E_PRODUCT_TYPE eProductType)
{
switch(eProductType)
{
case PRODUCT_A:
return new ProductA();
case PRODUCT_B:
return new ProductB();
case PRODUCT_C:
return new ProductC();
default:
return nullptr;
}
}
测试函数
cpp
void TestFactory()
{
std::unique_ptr<Factory> upFactory = std::make_unique<Factory>();
BaseProduct* pProductA = upFactory->CreateProduct(PRODUCT_A);
BaseProduct* pProductB = upFactory->CreateProduct(PRODUCT_B);
BaseProduct* pProductC = upFactory->CreateProduct(PRODUCT_C);
pProductA->Show(); // Show ProductA
pProductB->Show(); // Show ProductB
pProductC->Show(); // Show ProductC
delete pProductA;
delete pProductB;
delete pProductC;
}