C++ 深入浅出工厂模式(进阶篇)
介绍
前文初始篇C++ 深入浅出工厂模式(初始篇),主要阐述了简单工厂模式、工厂方法模式和抽象工厂模式的结构、特点和缺陷等。以上三种方式,在新增产品时,要么修改工厂类,要么需新增具体的工厂类,说明工厂类的封装性还不够好。
本文进阶篇,主要是将工厂类的封装性提高,达到新增产品时,也不需要修改工厂类,不需要新增具体的工厂类。封装性高的工厂类特点是扩展性高、复用性也高。
模板工厂
针对工厂方法模式封装成模板工厂类,那么这样在新增产品时,是不需要新增具体的工厂类,减少了代码的编写量。
UML图:
模板工厂代码:
Shoes
和Clothe
,分别为鞋子和衣服的抽象类(基类)NiKeShoes
和UniqloClothe
,分别为耐克鞋子和优衣库衣服具体产品类。
AbstractFactory
为抽象模板工厂类,其中模板参数:AbstractProduct_t
产品抽象类,如Shoes
、Clothe
ConcreteFactory
为具体模板工厂类,其中模板参数:AbstractProduct_t
产品抽象类(如Shoes
、Clothe
),ConcreteProduct_t
产品具体类(如NiKeShoes
、UniqloClothe
)
main
函数,根据不同类型的产品,构造对应的产品的工厂对象,便可通过对应产品的工厂对象创建具体的产品对象。
输出结果:
产品注册模板类+单例工厂模板类
前面的模板工厂虽然在新增产品的时候,不需要新增具体的工厂类,但是缺少一个可以统一随时随地获取指定的产品对象的类。
还有改进的空间,我们可以把产品注册的对象用std::map
的方式保存,通过key-valve
的方式可以轻松简单的获取对应的产品对象实例。
实现大致思路:
把产品注册的功能封装成产品注册模板类。注册的产品对象保存在工厂模板类的
std::map
,便于产品对象的获取。
把获取产品对象的功能封装成工厂模板类。为了能随时随地获取指定产品对象,则把工厂设计成单例模式。
UML图:
产品注册模板类+单例工厂模板类:
IProductRegistrar
为产品注册抽象类,模板参数ProductType_t
表示的类是产品抽象类(如Shoes
、Clothe
)。提供了产品对象创建的纯虚函数CreateProduct
。ProductFactory
为工厂模板类,模板参数ProductType_t
表示的类是产品抽象类(如Shoes
、Clothe
)。用于保存注册产品对象到std::map
中和获取对应的产品对象。ProductRegistrar
为产品注册模板类,模板参数ProductType_t
表示的类是产品抽象类(如Shoes
、Clothe
),ProductImpl_t
表示的类是具体产品(如NikeShoes
、UniqloClothe
)。用于注册产品到工厂类和创建产品实例对象。
main
函数,通过ProductRegistrar
注册各种不同类型产品,在统一由ProductFactory
单例工厂获取指定的产品对象。
输出结果:
总结
将工厂方法模式改良成模板工厂,虽然可以解决产品新增时,不需要新增具体工厂类,但是缺少一个可以随时随地获取产品对象的方式,说明还有改进的空间。
将模板工厂改良成产品注册模板类+单例工厂模板类,产品注册模板类用于注册不同类型的产品,单例工厂模板类用于获取指定已注册的产品对象。这种方式,可以把工厂模式中产品的注册和获取的主要功能很好的抽象成两个类,并且使用单例模式使得工厂类可以随时随地获取已注册的产品对象。
所以产品注册模板类+单例工厂模板类的工厂模式,达到了开闭法则,并且扩展性高和封装度高。
PS:想学习更多单例模式,可以参考C++ 线程安全的单例模式总结文章阅读。
版权声明: 本文为 InfoQ 作者【小林coding】的原创文章。
原文链接:【http://xie.infoq.cn/article/d95eda88dd0a2192b954403d5】。文章转载请联系作者。
评论