动机(续)
上面的类图说明了对象适配器实例。它说明了在Shape类中声明的BoundingBox请求如何被转换成在TextView类中定义的GetExtent请求。由于TextShape将TextView的接口与Shape的接口进行了匹配,因此绘图编辑器就可以复用原先并不兼容的TextView类。
这是适配器模式中使用已有功能的例子,BoundingBox是图形编辑软件一侧的要求,如果既有库一侧也具有类似的功能,那么就使用它。一般来讲这时会根据需要对参数,调用的接口进行调整。使用即有库中的功能是使用适配器模式的目的。
Adapter时常还要负责提供那些被匹配的类所没有提供的功能,上面的类图中说明了适配器如何实现这些职责。由于绘图编辑器允许用户交互的将每一个Shape对象“拖动”到一个新的位置,而TextView设计中没有这种功能。我们可以实现TextShape类的CreateManipulator操作,从而增加这个缺少的功能,这个操作返回相应的Manipulator子类的一个实例。
当然也存在某些功能需既有库中中不支持的情况。这时就需要再适配器中实现。一般来讲,自己实现的部分应该是相对容易,且工作量较小的部分,否则使用适配器模式的效果就会打折扣了。
Manipulator是一个抽象类,它所描述的对象知道如何驱动Shape类响应相应的用户输入,例如将图形拖动到一个新的位置。对应于不同形状的图形,Manipulator有不同的子类;例如子类TextManipulator对应于TextShape。TextShape通过返回一个TextManipulator实例,增加了TextView中缺少而Shape需要的功能。
生成Manipulator实例也是图形编辑软件的需要,适配器的实例可以生成适合于自己的Manipulator具象类,而这个类可以只使用图形编辑软件定义的功能,也可以使用即有库的功能。
作者观点
一般情况下,即有库的功能不大可能和需要的功能完全一致,经常会多出一些不需要的功能,同时又会缺少一些需要的功能。多出的部分会造成软件维护,发布的负担;不足的部分会影响软件的开发量。在实际的开发中往往需要通览全局,平衡考虑。
注:
本文中
蓝 {MOD}粗体文字都引自《设计模式》一书。
觉得本文有帮助?请分享给更多人。
阅读更多更新文章,请扫描下面二维码,关注微信公众号【面向对象思考】