5) 用类动态配置应用
一些运行时刻环境允许你动态将类装载到应用中。在像 C++这样的语言中,Prototype模式是利用这种功能的关键。
某些开发环境可以(例如通过系列化的方式)在程序执行的时侯加载类。这些类被加载以后的用法可分为两种情况:直接使用和作为生成其他对象的模板。第二中方法的关键就是原型模式。
一个希望创建动态载入类的实例的应用不能静态引用类的构造器。而应该由运行环境在载入时自动创建每个类的实例,并用原型管理器来注册这个实例(参见实现一节)。这样应用就可以向原型管理器请求新装载的类的实例,这些类原本并没有和程序相连接。 ET++应用框架[WGM88]有一个运行系统就是使用这一方案的。
一般来讲,被动态载入的类应该认为是事先定义好的基类的某种派生类。所以很可能没办法知道(也不应该知道)具体的类型。结果就是没有办法使用类的构造函数(即译文中的构造器)。这个问题可以用原型模式来解决。
我们可以参照的Word软件中的图库功能来理解这件事。
首先是载入图库,也就是打开图库文件操作。这个打开文件的过程实际上就是读出保存在文件中的复合图形数据并在内存中构建复合图形实例的过程。这些复合图形实例生成后登录到原型管理器上备用。当我们从图库中选择图形时打开的画面中显示的就是原型管理器中的图形实例。
接下来,用户会选择某个图形拖放到作图区。这个操作从程序实现的角度来看就是向原型管理器请求复合图形的新实例的过程。只要实现定义好合适的接口,Word完全可以导入在另外的地方定义的新类。这就保证的这个过程的扩展性。
Prototype的主要缺陷是每一个Prototype的子类都必须实现Clone操作,这可能很困难。例如,当所考虑的类已经存在时就难以新增Clone操作。当内部包括一些不支持拷贝或有循环引用的对象时,实现克隆可能也会很困难的。
克隆方法作为原型模式中生成实例的手段,当然是需要代价的。考虑为某个已经存在的类群增加克隆方法的情况:如果这个类群中每个类构成都不一样,工作量就会很大;如果存在无法拷贝的信息(例如指向拷贝范围之外的引用)或循环引用,就需要更加细致的整理和设计。
作者观点
设计者在遇到上述问题时,正视技术/方法的优点和缺点并在实际工作中尝试使用的决心和技能都是需要的。
注:
本文中
蓝 {MOD}粗体文字都引自《设计模式》一书。
觉得本文有帮助?请分享给更多人。
阅读更多更新文章,请扫描下面二维码,关注微信公众号【面向对象思考】