博客
关于我
C++ 深入浅出工厂模式(进阶篇)
阅读量:502 次
发布时间:2019-03-07

本文共 3222 字,大约阅读时间需要 10 分钟。

优化工厂模式:从模板工厂到产品注册模板类+单例工厂模板类

在前文中,我们探讨了工厂方法模式的局限性:当新增产品时,往往需要修改工厂类或新增具体工厂类,导致工厂类的封装性不足。为了解决这一问题,本文将工厂方法模式进一步优化,提出了模板工厂和产品注册模板类+单例工厂模板类两种方案。

模板工厂

模板工厂通过将工厂类的功能参数化,实现了工厂类的封装性提升。在新增产品时,不需要修改工厂类,也无需新增具体工厂类。这种方式减少了代码编写量,提高了扩展性和复用性。

核心特点

  • 参数化工厂类:模板工厂采用模板参数,将产品的抽象类和具体类统一处理。
  • 减少代码复制:新增产品时,只需扩展具体产品类和工厂类,避免重复代码。
  • 统一管理:通过单例工厂实现工厂对象的唯一性,提升了工厂对象的管理效率。
  • 代码示例

    // 基类 鞋子class Shoes {public:    virtual void Show() = 0;    virtual ~Shoes() {}};// 具体产品类:耐克鞋class NiKeShoes : public Shoes {public:    void Show() {        std::cout << "我是耐克球鞋,我的广告语:Just do it" << std::endl;    }};// 基类 衣服class Clothe {public:    virtual void Show() = 0;    virtual ~Clothe() {}};// 具体产品类:优衣库衣服class UniqloClothe : public Clothe {public:    void Show() {        std::cout << "我是优衣库衣服,我的广告语:I am Uniqlo" << std::endl;    }};// 模板抽象工厂类template 
    class AbstractFactory {public: virtual AbstractProduct_t *CreateProduct() = 0; virtual ~AbstractFactory() {}};// 具体模板工厂类template
    class ConcreteFactory : public AbstractFactory
    {public: AbstractProduct_t *CreateProduct() { return new ConcreteProduct_t; }};

    产品注册模板类+单例工厂模板类

    模板工厂虽然提升了封装性,但仍缺少统一管理产品对象的功能。产品注册模板类+单例工厂模板类进一步优化这一问题。

    核心特点

  • 产品注册模板类:用于注册不同类型产品,通过std::map保存产品对象,支持快速获取。
  • 单例工厂模板类:通过单例设计实现工厂对象的唯一性,支持随时获取指定产品对象。
  • 扩展性高:新增产品时,只需注册产品和创建具体类,不需修改工厂类。
  • 代码示例

    // 产品注册模板类template 
    class IProductRegistrar {public: virtual ProductType_t *CreateProduct() = 0; IProductRegistrar() {} ~IProductRegistrar() {} IProductRegistrar(const IProductRegistrar &) {} const IProductRegistrar &operator=(const IProductRegistrar &) {}};// 单例工厂模板类template
    class ProductFactory {public: static ProductFactory
    &Instance() { static ProductFactory
    instance; return instance; } void RegisterProduct(IProductRegistrar
    *registrar, std::string name) { m_ProductRegistry[name] = registrar; } ProductType_t *GetProduct(std::string name) { if (m_ProductRegistry.find(name) != m_ProductRegistry.end()) { return m_ProductRegistry[name]->CreateProduct(); } std::cout << "No product found for " << name << std::endl; return NULL; }private: ProductFactory() {} ~ProductFactory() {} ProductFactory(const ProductFactory &) {} const ProductFactory &operator=(const ProductFactory &) {} std::map
    *> m_ProductRegistry;};// 产品注册模板类template
    class ProductRegistrar : public IProductRegistrar
    {public: ProductRegistrar(std::string name) { ProductFactory
    ::Instance().RegisterProduct(this, name); } ProductType_t *CreateProduct() { return new ProductImpl_t; }};

    实现示例

    int main() {    // 注册耐克球鞋    ProductRegistrar
    nikeShoes("nike"); Shoes *pNiKeShoes = ProductFactory
    ::Instance().GetProduct("nike"); pNiKeShoes->Show(); // 注册优衣库衣服 ProductRegistrar
    adidasShoes("uniqlo"); Clothe *pUniqloClothe = ProductFactory
    ::Instance().GetProduct("uniqlo"); pUniqloClothe->Show(); delete pNiKeShoes; delete pUniqloClothe; return 0;}

    总结

    通过将工厂方法模式优化为模板工厂,再到产品注册模板类+单例工厂模板类,我们实现了工厂类的高效管理和产品对象的统一获取。这种方式不仅提升了工厂类的封装性和扩展性,还符合开闭原则,使得产品的管理更加灵活和高效。

    转载地址:http://szzcz.baihongyu.com/

    你可能感兴趣的文章
    Openlayers实战:非4326,3857的投影
    查看>>
    Openlayers高级交互(1/20): 控制功能综合展示(版权、坐标显示、放缩、比例尺、测量等)
    查看>>
    Openlayers高级交互(10/20):绘制矩形,截取对应部分的地图并保存
    查看>>
    Openlayers高级交互(11/20):显示带箭头的线段轨迹,箭头居中
    查看>>
    Openlayers高级交互(12/20):利用高德逆地理编码,点击位置,显示坐标和地址
    查看>>
    Openlayers高级交互(13/20):选择左右两部分的地图内容,横向卷帘
    查看>>
    Openlayers高级交互(14/20):汽车移动轨迹动画(开始、暂停、结束)
    查看>>
    Openlayers高级交互(15/20):显示海量多边形,10ms加载完成
    查看>>
    Openlayers高级交互(16/20):两个多边形的交集、差集、并集处理
    查看>>
    Openlayers高级交互(17/20):通过坐标显示多边形,计算出最大幅宽
    查看>>
    Openlayers高级交互(18/20):根据feature,将图形适配到最可视化窗口
    查看>>
    Openlayers高级交互(19/20): 地图上点击某处,列表中显示对应位置
    查看>>
    Openlayers高级交互(2/20):清除所有图层的有效方法
    查看>>
    Openlayers高级交互(20/20):超级数据聚合,页面不再混乱
    查看>>
    Openlayers高级交互(3/20):动态添加 layer 到 layerGroup,并动态删除
    查看>>
    Openlayers高级交互(4/20):手绘多边形,导出KML文件,可以自定义name和style
    查看>>
    Openlayers高级交互(5/20):右键点击,获取该点下多个图层的feature信息
    查看>>
    Openlayers高级交互(6/20):绘制某点,判断它是否在一个电子围栏内
    查看>>
    Openlayers高级交互(7/20):点击某点弹出窗口,自动播放视频
    查看>>
    Openlayers高级交互(8/20):选取feature,平移feature
    查看>>