重构到扩展方法(5):动态给实例增加行为
情景1:
我们知道,我们在使用一个对象的时候,它有哪些行为,都是类写死的。
当我们想给其增加一个行为(方法)的时候,我们怎么办?
只能修改其源代码,新增一个方法了事?可这样做?不是违背了——开放封闭原则了么?
情景2:
OO三大原则:继承。继承的好处是可以少写代码。可一旦继承树大起来,我们对象就变得肥胖起来。
如果按继承设计WPF,那么我们每次New一个Button,就继承了N多属性,但其实用到的只是常用的几个,比如“Button.Context"。
一味的用继承,是个坏味道。所以有人提出 使用组合而不用继承。但组合也有局限,组合模式的前提就是需要零部件对象实现某个接口方法,而类内部保持引用,并增加一个方法。但这也是类写死的,也就是说,想增加方法只能修改源代码。
而使用扩展方法,我们就可以轻松不修改源码给其增加功能。
比如Array没有,从后向前去N个数据项的方法。但因为其是.net FCL,无法改源码,那怎么办呢?我们可以使用扩展方法:
public static IEnumerable<T> GetFromEnd<T>(this T[] array, int count) { for (int i = array.Length - 1; i > array.Length - 1 - count; i--) { yield return array[i]; } }
这样,Array就有了GetFromEnd方法了。
至此,我们可以总结一种思想:一个类设计时只需要其最基本的方法。不用碰倒一个需求就增加方法。其实你用脑子想一想,哪些是类应有的,哪些是必须使用的,哪些是可选的,哪些是在某种情况下用的?哪些方法很少使用?
动态给实例增加行为,这也是扩展方法的精髓。