热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

PluggableObjectFactory可插入式对象工厂

     ITK 中使用的其实是种称为 pluggable object factory 的设计模式,它可以在运行时进行动态替换,而且可以不修改已有代码的情况下添加处理新格

     ITK 中使用的其实是种称为 pluggable object factory 的设计模式,它可以在运行时进行动态替换,而且可以不修改已有代码的情况下添加处理新格式的图像文件类,等还有一些其它优点。它由两种模式组合而成:1.Abstract Factory 抽象工厂;2. Prototype 原型模式。还可能与单件模式(Singleton)组合。

简单的对象工厂可能如下所示:

1:  

2: //Simple Factory

3: Circle

4: {

5: double radius;

6: }

7:  

8: class Shape

9: {

10: public:

11: static Shape* newShape(istream&);

12: };

13: Shape* Shape::newShape(istream& params)

14: {

15: string className;

16: params >> className;

17: if (className == "Circle")

18: return new Circle(params);

19: else if (className == "Triangle")

20: return new Triangle(params);

21: else

22: //…

23: }

24:  


Shape 是一个用来创建不同形状的对象工厂,Circle 是一种具体的形状。对象工厂 Shape 通过判断传入的参数,创建不同的对象实例。简单对象工厂的问题在于:1.基类 Shape 必须知道从它继承的每一个具体子类。2.当需要添加一种新的形状时,就得修改工厂方法 newShape()。这就违背了面向对象设计的“依赖倒置”原则(Dependency Inversion Principle),即高层模块不应该依赖于低层模块。同时还违背了“开-闭”原则(Opened-Closed),即 Open to extension,Closed to Modification。Pluggable Object Factory 模式可以解决这些问题。

Pluggable Object Factory,或者称为 PROTOTYPE–ABSTRACT FACTORY,可以将该模式归为创建型一类。

     使用一个关联式容器如 map,关联容器中的每一个元素都是一个对象工厂,该对象工厂知道如何从一个抽象类层次结构中创建具体的子类对象实例。关联容器中的 key 则是用来从容器中查找合适的对象工厂。

Prototype Factory Compound Pattern:使用工厂方法,我们创建一个抽象类 ShapeMaker,它有一个静态的公有方法 newShape。一个具体的 CircleMaker 知道如何创建 circle 对象,它继承自 ShapeMaker。

1: //

2: class ShapeMaker

3: {

4: public:

5: static Shape* newShape(istream&);

6: protected:

7: typedef map<string,ShapeMaker*> MakerMap;

8: virtual Shape* makeShape(istream&) const&#61;0;

9: static MakerMap registry;

10: };

11: Shape* ShapeMaker::newShape(istream& is) {

12: string className;

13: is >> className;

14: ShapeMaker* maker &#61;

15: (*registry.find(className)).second;

16: return maker->makeShape(is);

17: }

18: //

19: class CircleMaker : public ShapeMaker

20: {

21: private:

22: Shape* makeShape(istream& params) const

23: {

24: return new Circle(params);

25: }

26: };

27:  



     同样&#xff0c;我们可以创建新的具体工厂类&#xff0c;如 TriangleMaker、RectangleMaker 等。每一个具体的工厂的实例都被保存于一个关联容器中。基类 ShapeMaker 通过一个 key 关联具体的工厂子类&#xff0c;如上面代码所示这里的 key 使用的是类名 className。 newShape(className) 通过在关联容器中查找对应于 className 的具体的对象工厂来创建具体的对象实例。这样&#xff0c;我们便可以不修改工厂方法而添加新的对象工厂。

Registering Factories Using Prototype&#xff1a;Prototype 原型模式提供了在关联容器中动态注册对象工厂的方法。每一个具体的对象工厂都维护一个自身的静态对象实例变量&#xff0c;该静态对象实例的唯一目的就是在基类的静态关联容器中注册自己。

1:  

2: //

3: class CircleMaker : public ShapeMaker

4: {

5: private:

6: CircleMaker() : ShapeMaker("Circle") {}

7: static const CircleMaker registerThis;

8: };

9: //其中&#xff1a;

10: ShapeMaker::ShapeMaker(string className)

11: {

12: //在基类的静态关联容器中注册自己

13: registry.insert( make_pair(className, this) );

14: }

15: //使用&#xff1a;

16: fstream params("shapes.txt");

17: Shape* shape &#61; ShapeMaker::newShape(params);

18:  

 

Plugging in with Prototype Factory&#xff1a;Factory Method 工厂方法与 Prototype 原型模式结合&#xff0c;允许工程扩展 ShapeMaker可以创建对象的 Shape 类型。ShapeMaker 类以及与其协作的其它类表示了 Prototype Factory 模式。Factory Method 工厂方法提供创建对象实例的方法&#xff0c;Prototype 原型模式提供在运行时动态注册对象工厂的方法。

1.GENERIC FACTORIES 泛化工厂&#xff1a;从上面的 Prototype Factory 模式可以看出&#xff0c;算法与数据类型是相互独立的&#xff0c;所以我们使用模板实现 Prototype Factory 组合模式&#xff1a;

1:  

2: //Generic 工厂

3: template<class Object>

4: class Maker

5: {

6: public:

7: virtual ~Maker();

8: static Object* newObject(istream&);

9: protected:

10: Maker(const string& className);

11: virtual Object* makeObject(istream&) const&#61;0;

12: private:

13: typedef Maker



推荐阅读
  • 项目需要将音视频文件上传服务器,考虑并发要求高,通过七牛来实现。直接上代码usingQiniu.IO;usingQiniu.IO.Resumable;usingQiniu.RPC; ... [详细]
  • 本文介绍了lua语言中闭包的特性及其在模式匹配、日期处理、编译和模块化等方面的应用。lua中的闭包是严格遵循词法定界的第一类值,函数可以作为变量自由传递,也可以作为参数传递给其他函数。这些特性使得lua语言具有极大的灵活性,为程序开发带来了便利。 ... [详细]
  • Spring源码解密之默认标签的解析方式分析
    本文分析了Spring源码解密中默认标签的解析方式。通过对命名空间的判断,区分默认命名空间和自定义命名空间,并采用不同的解析方式。其中,bean标签的解析最为复杂和重要。 ... [详细]
  • VScode格式化文档换行或不换行的设置方法
    本文介绍了在VScode中设置格式化文档换行或不换行的方法,包括使用插件和修改settings.json文件的内容。详细步骤为:找到settings.json文件,将其中的代码替换为指定的代码。 ... [详细]
  • 向QTextEdit拖放文件的方法及实现步骤
    本文介绍了在使用QTextEdit时如何实现拖放文件的功能,包括相关的方法和实现步骤。通过重写dragEnterEvent和dropEvent函数,并结合QMimeData和QUrl等类,可以轻松实现向QTextEdit拖放文件的功能。详细的代码实现和说明可以参考本文提供的示例代码。 ... [详细]
  • Webpack5内置处理图片资源的配置方法
    本文介绍了在Webpack5中处理图片资源的配置方法。在Webpack4中,我们需要使用file-loader和url-loader来处理图片资源,但是在Webpack5中,这两个Loader的功能已经被内置到Webpack中,我们只需要简单配置即可实现图片资源的处理。本文还介绍了一些常用的配置方法,如匹配不同类型的图片文件、设置输出路径等。通过本文的学习,读者可以快速掌握Webpack5处理图片资源的方法。 ... [详细]
  • 原文地址:https:www.cnblogs.combaoyipSpringBoot_YML.html1.在springboot中,有两种配置文件,一种 ... [详细]
  • 本文主要解析了Open judge C16H问题中涉及到的Magical Balls的快速幂和逆元算法,并给出了问题的解析和解决方法。详细介绍了问题的背景和规则,并给出了相应的算法解析和实现步骤。通过本文的解析,读者可以更好地理解和解决Open judge C16H问题中的Magical Balls部分。 ... [详细]
  • 知识图谱——机器大脑中的知识库
    本文介绍了知识图谱在机器大脑中的应用,以及搜索引擎在知识图谱方面的发展。以谷歌知识图谱为例,说明了知识图谱的智能化特点。通过搜索引擎用户可以获取更加智能化的答案,如搜索关键词"Marie Curie",会得到居里夫人的详细信息以及与之相关的历史人物。知识图谱的出现引起了搜索引擎行业的变革,不仅美国的微软必应,中国的百度、搜狗等搜索引擎公司也纷纷推出了自己的知识图谱。 ... [详细]
  • Python SQLAlchemy库的使用方法详解
    本文详细介绍了Python中使用SQLAlchemy库的方法。首先对SQLAlchemy进行了简介,包括其定义、适用的数据库类型等。然后讨论了SQLAlchemy提供的两种主要使用模式,即SQL表达式语言和ORM。针对不同的需求,给出了选择哪种模式的建议。最后,介绍了连接数据库的方法,包括创建SQLAlchemy引擎和执行SQL语句的接口。 ... [详细]
  • 全面介绍Windows内存管理机制及C++内存分配实例(四):内存映射文件
    本文旨在全面介绍Windows内存管理机制及C++内存分配实例中的内存映射文件。通过对内存映射文件的使用场合和与虚拟内存的区别进行解析,帮助读者更好地理解操作系统的内存管理机制。同时,本文还提供了相关章节的链接,方便读者深入学习Windows内存管理及C++内存分配实例的其他内容。 ... [详细]
  • 本文介绍了H5游戏性能优化和调试技巧,包括从问题表象出发进行优化、排除外部问题导致的卡顿、帧率设定、减少drawcall的方法、UI优化和图集渲染等八个理念。对于游戏程序员来说,解决游戏性能问题是一个关键的任务,本文提供了一些有用的参考价值。摘要长度为183字。 ... [详细]
  • Jboss的EJB部署描述符standardjaws.xml配置步骤详解
    本文详细介绍了Jboss的EJB部署描述符standardjaws.xml的配置步骤,包括映射CMP实体EJB、数据源连接池的获取以及数据库配置等内容。 ... [详细]
  • 如何自行分析定位SAP BSP错误
    The“BSPtag”Imentionedintheblogtitlemeansforexamplethetagchtmlb:configCelleratorbelowwhichi ... [详细]
  • 集合的遍历方式及其局限性
    本文介绍了Java中集合的遍历方式,重点介绍了for-each语句的用法和优势。同时指出了for-each语句无法引用数组或集合的索引的局限性。通过示例代码展示了for-each语句的使用方法,并提供了改写为for语句版本的方法。 ... [详细]
author-avatar
拍友2502878393
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有