一、意图
定义一个用于创建对象的接口,让子类决定实例化哪一个对象。说人话就是:将创建对象的工作交给一个“工厂”来完成。
二、UML图
我们在抽象Creator中的的FactoryMethod如下,这里的形式参数可以设置一些值,以选择返回特殊的产品(这里使用模板而没用这种技巧):
template<class AbstractProduct_t>
class AbstractFactory
{
public:
virtual AbstractProduct_t* CreateProduct() = 0;
};
在下面的具体Creator中,我们返回创建的产品:
template<class AbstractProduct_t, class ConcreteProduct_t>
class ConcreteFactory
{
public:
AbstractProduct_t* CreateProduct()
{
return new ConcreteProduct_t();
}
};
三、实例
下面我们来看一段实例,我们有两个抽象产品:shoes和clothe,我们的具体产品是nikeShoes和uniqloClothe。我们通过c++的模板操作来对工厂模式做一个改进:
// 抽象类(产品) 01 : 鞋子
class Shoes
{
public:
virtual void show() = 0;
};
// 抽象类(产品) 02 : 衣服
class Clothe
{
public:
virtual void show() = 0;
};
// 具体产品 01 : Nike Shoes
class NikeShoes : public Shoes
{
public:
void show()
{
std::cout << "Nike Shoes" << std::endl;
}
};
// 具体产品 02 : Uniqlo Clothe
class UniqloClothe : public Clothe
{
public:
void show()
{
std::cout << "Uniqlo Clothe" << std::endl;
}
};
// 工厂方法同上
int main()
{
// 构造耐克鞋的工厂对象
ConcreteFactory<Shoes, NikeShoes> nikeFactory;
// 创建耐克鞋对象
Shoes* pNiKeShoes = nikeFactory.CreateProduct();
// 打印耐克鞋广告语
pNiKeShoes->show();
// 构造优衣库衣服的工厂对象
ConcreteFactory<Clothe, UniqloClothe> uniqloFactory;
// 创建优衣库衣服对象
Clothe* pUniqloClothe = uniqloFactory.CreateProduct();
// 打印优衣库广告语
pUniqloClothe->show();
// 释放资源
delete pNiKeShoes;
pNiKeShoes = NULL;
delete pUniqloClothe;
pUniqloClothe = NULL;
return 0;
}
四、缺陷与改进
上面的方法比较死板,如果想要完成(服装类型 x 品牌)的组合则需要使用抽象工厂模式(Abstract Factory),这个模式我们将在下一篇文章中介绍。这里我们引入注册机的机制来创建一种新的工厂模式,产品注册模板类+单例工厂模板类:
我们的产品保持不变:Shoes、NikeShoes、Clothe和UniqloClothe。
4.1 抽象注册机 – IProductRegister
template<class ProductType_t>
class IProductRegister
{
private:
// 禁止外部拷贝和赋值
IProductRegister(const IProductRegister&) = delete;
const IProductRegister& operator=(const IProductRegister&) = delete;
protected:
// 禁止外部构造与析构,允许子类其他函数调用
IProductRegister() {}
virtual ~IProductRegister() {}
public:
// 获取抽象产品接口
virtual ProductType_t* CreateProduct() = 0;
};
4.2 工厂 – ProductFactory
template<class ProductType_t>
class ProductFactory
{
private:
// 禁止外部构造与析构
ProductFactory() {}
~ProductFactory() {}
// 禁止外部拷贝与赋值
ProductFactory(const ProductFactory&) = delete;
const ProductFactory& operator=(const ProductFactory&) = delete;
// 保存已经注册的产品
std::map<std::string, IProductRegister<ProductType_t>*> m_ProductRegistry;
public:
// 或得工厂单例、工厂实例唯一
static ProductFactory<ProductType_t>& Instance()
{
static ProductFactory<ProductType_t> instance;
return instance;
}
// 产品注册
void RegisterProduct(IProductRegister<ProductType_t>* p_register, std::string productName)
{
m_ProductRegistry[productName] = p_register;
}
ProductType_t* GetProduct(std::string productName)
{
// 已注册则返回产品
if (m_ProductRegistry.count(productName) > 0)
{
return m_ProductRegistry[productName]->CreateProduct();
}
std::cout << "product not exist" << std::endl;
return nullptr;
}
};
4.3 具体注册机 – ProductRegister
template<class ProductType_t, class ProductImpl_t>
class ProductRegister : public IProductRegister<ProductType_t>
{
public:
// 显式将产品注册到工厂
explicit ProductRegister(std::string productName)
{
ProductFactory<ProductType_t>::Instance().RegisterProduct(this, productName);
}
ProductType_t* CreateProduct()
{
return new ProductImpl_t();
}
};
4.4 在main中使用
int main()
{
// 注册shoes(basic), NikeShoes(dep)到工厂,取名为NikeShoes
ProductRegister<Shoes, NikeShoes> registeNikeShoes("NikeShoes");
Shoes* pNikeShoesPtr = ProductFactory<Shoes>::Instance().GetProduct("NikeShoes");
pNikeShoesPtr->show();
pNikeShoesPtr != nullptr ? delete pNikeShoes :
void();
// 注册colthe - uniqloClothe到工厂,取名为UniqloClothe
ProductRegister<Clothe, UniqloClothe> resgiteUniqloClothe("UniqloClothe");
Clothe* pUniqloClothePtr = ProductFactory<Clothe>::Instance().GetProduct("UniqloClothe");
pUniqloClothePtr->show();
pUniqloClothePtr != nullptr ? delete pUniqloClothe :
void();
return 0;
}