从SourceGrid2想到的继承复用与合成复用

研究SourceGrid2的时候,有一点觉得很别扭:若要实现一个自己的可视样式(VisualModel)、数据样式(DataModel)或行为样式(BehaviorModel),多数情况下都是通过写自己的继承类来实现,在子类中重写自己需要特殊动作的父类方法。而对习惯于用微软BCL基础类库编程的人来说,这样的工作一般是通过订阅、处理事件来完成。订约、处理事件看起来比继承、重写个On****()方法简单多了。

因为没有多少面向对象编程的理论造诣,冥冥中只是觉得别扭而已。今天在  jb303 的专栏 《面向对象的设计与实现的一些基础但重要的概念》中看到“继承复用”与“合成聚合复用”的概念,查了一下,总算为自己的这一自发想法找到了些理论依据。

这个问题往大了说可以归到软件复用技术的范畴,SourceGrid2中用的是继承复用,而我觉得更好的那种方式叫“合成/聚合复用原则(Composite/Aggregate Reuse Principle或CARP),经常又叫做合成复用原则(Composite Reuse Principle或CRP),就是在一个新的对象里面使用一些已有的对象,使之成为新对象的一部分;新对象通过向这些对象的委派达到复用已有功能的目的。”——摘自阎宏《Java与模式》。

把问题简单化,假设我们要复用的“已有功能”用方法 MethodA() 来表示。.Net的事件委托机制符合了合成复用原则的“新对象通过向这些对象的委派达到复用已有功能的目的”这句话,“新对象”通过订阅“这些对象”的事件,把 MethodA() “委派”给了“这些对象”,所有“这些对象”都具有了 MethodA() 的功能。这个工作如果换成用继承来实现,应该是写一个继承自“这些对象”类型的子类,重写其On****()方法以实现 MethodA() 的特殊功能,然后在“新对象”中使用的所有子类的对象也具有了 MethodA() 的功能。

比较一下继承复用和用事件委托机制实现的合成复用,其实也各有利弊。
继承复用
优点:彻底的灵活性,可以把基类的功能完全重写。
缺点:破坏封装性,静态、白盒复用。
事件委托机制实现的合成复用
优点:功能可无限扩展
缺点:无法屏蔽“这些对象”原有的处理方法。

posted on 2005-03-19 10:31  阳春三月  阅读(1427)  评论(1编辑  收藏  举报

导航