复用可以说是任何一个软件企业都不能漠视的课题,因为复用可能对软件的开发效能产生绝大影响,而开发效能直接影响利润,甚至生存。
但复用本身将增加当前项目的成本,是一种以当前投入来换取远期收益的行为。与此同时远非所有代码都可以复用,复用本身也有自己内在的一些规律,让我们来试做一些分析。
从结论上来说,只有满足下面两条原则的程序,才可能真正的被复用,否则的话只能采用代码级别的复用。
***条原则是,程序本身的职能非常独立与业务层面基本无关联,是功能型的模块(包)。
代码中的逻辑表述的是一种关联性,当这种关联只在确定的方面存在的时候,通常我们可以切割出比较独立的模块,而这种模块可以成为复用的基础之一。这也就是常说的【闭包】。
这种复用有许多表现形式,但其本质相同。
比如JPEG的库,XML的库,比如我们常提到的组件或控件。
在这类复用中扮演关键角色的是一组接口,以及这组接口的基本使用规则。
REP(重用发布等价原则),CRP(共同重用原则)中提到的重用都是这类重用。
第二条原则是,程序本身所描述的过程足够抽象,同具体实现细节可以切的很开。
概念在衍化的过程中其内含的细节会逐渐丰富,但又会共享某些共同的基本特征。很多时候逻辑要处理的是这种根本特征,而非细节。在这个时候,就需要抽象。
好比人可以分为男人和女人,也可以分为老人,青年人和小孩。但因为同属于人这一范畴,所以不管如何分类,必有共通之处。也正因此,某些针对【人】的规则或者价值标准是可以通用于所有人的,即是可以复用的。比如说法律。大多时候,我们不需要指定分别针对于男人,女人的法律
这种类型的复用不是很好理解,我们用迭代器的例子来进行进一步的说明。
当我们想遍历一个容器的时候,从【头到尾的循环】和【逐个遍历】是属于任何容器的,而同具体的容器无关。但如何从***个元素,遍历到第二个元素则和容器的具体实现有关。把这种和具体实现细节无关的逻辑提取出来的过程,也即抽象的过程。只有能做到这种程度抽象,非独立的功能性的代码才可能真正的做到被重用。
《设计模式》这本书有个副标题,叫《可复用面向对象软件的基础》。基础这个词的意指与上述说明相同。
由第二条原则而产生的复用的形式可以是,设计模式与框架。历史上的MFC的文档视图结构就是一个典型代表。
一个比较典型的是近来很受关注的Map-Reduce的函数式编程方法,据说这种方法在Google被用来支持并行计算。--参见《软件随想录》
假设说某一功能的主要部分已经实现,比如排序。这时候已经实现的部分是既定算法,可能是选择排序,也可能是插入排序。但对于排序而言,对两个数值进行比较的部分则依赖于被比较的对象,需要被灵活指定。这也就意味着重用排序的实现,等于实现两段代码的对接,实现一部分代码,但另一部分则由用的人在使用的时候指定。
这种方法可以更好的支持并行计算的原因在于,他可以把实现中的可优化部分分割开来。对于查询而言,如何遍历所有数据是可以并行优化的。
如果上述两条原则都无法满足,那么为了达到提升效能的目的,就需要做以实现为基础的代码级别的复用,即完全不做抽象,直接复用代码片段---也许这反倒是应用的最为广泛的复用方法。
很多人恐怕已经习惯了解决某个具体问题前,先到codeproject.com或者codeguru.com上确认一下有没有参考代码。如果不论这种方法的诸多缺点,比如:版权问题,引起代码风格混乱等等,这种方法的现实意义仍是比较巨大。其正面意义可以体现为下面几个方面:
可执行的代码片段可以清楚的告诉我们类库API等等的具体用法,进而缩短我们掌握领域知识的时间。在具体项目中使用某种语言,完全从零开始来完成某项工作的机会非常***,我们更多的时候要依赖于某些通用的领域知识。而通过帮助文档来学习类库等的使用方法效率相对低下,而这种可执行的片段代码则精准,且具体的描述了类库等的某一使用方法,使程序员可以更快上手。
可执行的代码片段可以是高质量的。如果我们承认代码的质量是要持续提高,那么这类代码片段,无疑的可以拥有比刚刚写成的代码更高的质量。因此这类代码对生产率的贡献还不仅只与提高编码速度。
如果真的想在组织中使用这种复用方法的话,一个关键点是要控制可执行代码片段的规模。
原文链接:http://www.cnblogs.com/daoshi/archive/2012/03/07/2382932.html
【编辑推荐】