在开发工作中,我们常常要将整体的开发内容分解成一些较小的部分,分而治之。 原因不限于以下几种:

  • 分解和抽象使得开发内容更容易被理解。
  • 可以将分解后的开发内容分配给多人开发。
  • 分解后的开发时间更容易估算,进度更易于衡量,有利于做计划。

古人说“横看成岭侧成峰”,意指从不同的角度观察事物时会得到不同的抽象。开发工作与之类似,当开发者从不同的角度进行分解工作时,会对开发内容产生不同的理解,因此分解后得出的产物可能也并不相同。从哪些角度对开发内容的分解才是最优的?这往往没有固定的答案,要由分解的目的决定。下面会介绍9种常见分解角度。

本文链接:https://www.cnblogs.com/hhelibeb/p/13070646.html

转载请注明

形式与结构

形式与结构,指的是开发内容中全部的开发对象,以及它们之间的关系。比如,一个客户信用检查程序可能包含表、视图、锁对象、接口、类等一些开发对象,它们之间会存在一定的连接关系。

从这个角度分解的优点在于它十分具体,有一些属性可以通过求和直接得到,比如,表和字段的数量意味着要增加多少种存储信息。

对形式的分析可以提示开发者将连接关系较多的东西归为一组,如果把它们分解到不同的地方,可能会导致复杂度增加,需要很多额外的工作来传递信息,对开发内容的分析和理解将变得困难。

功能

形式代表了静态存在的对象,而功能是指它们能做什么。功能是开发工作的价值体现。

一般来说,程序的命名即可提现它的功能。比如“供应商信用检查程序”显然指出了程序的功能是检查供应商的信用。如果将这个程序从功能角度分解,可以分解为设定信用额度的功能、计算占用额度的功能、集成到付款/采购流程的功能、从外部系统查询供应商信用的功能等。

按功能分解开发对象是最直观的分解方式之一,它有助于开发者从系统整体层面思考问题。比如,如果要考虑程序的性能问题,从功能角度的分解可以让人分析各个子功能的性能如何、它们集成到一起时有可能发生什么问题。又比如,如果要增加一个“黑名单/白名单”子功能的话,我们可以从功能角度审视这一新功能对其它各个子功能产生何种影响。

设计的自由度

如果能把紧密耦合的对象归为一个模块,并使之与外界尽可能的隔离,就能在模块内部得到更大的自由度。

这里以abap-data-validator为例,该项目的每个检查规则都位于单独的类中,这些类实现了同一个接口ZIF_ADV_CHECK,如下图。这使得每个类的开发者不需要与其它类的开发者共享任何信息,可以在自己负责的类中任意发挥,实现功能。而ZIF_ADV_CHECK约束了这些类,使它们遵循相同的检查接口约定。

开发内容分解的9个角度-LMLPHP

另一种思路是把这些检查功能都放置在同一个类中,用不同的类方法实现它们,如下图。显而易见,这样做的好处是降低了总体复杂度(方法数不变,类减少为1个),缺点是不同的方法会共享类的信息,有可能出现一些跨方法的东西,这会降低设计的自由度。对检查接口的约束也成为了一种隐式的规则,这会增大开发者的心智负担,容易产生误解。

开发内容分解的9个角度-LMLPHP

这两种做法没有绝对的优劣,abap-data-validator选择了前者,是因为开发者在经过权衡后认为,为了让社区的同行方便地增加自己的新的检查规则,付出增加一定的复杂度的代价是可以接受的。虽然到目前为止尚还没有人给这个项目贡献新规则。

程序的进化

程序的功能通常有不断增加的趋势 ,我们把功能增加的过程称为进化。从进化的角度进行分解时,开发者需要考虑如何让新旧功能方便地结合。以创建采购订单的程序为例,如果考虑到程序未来会有对订单进行其它检查的需求,那么就要分解出单独的检查模块,并提供接口。这样的话,如果要增加供应商信用检查功能,那么只要通过这个接口来实现就好。从进化角度的分解可以让程序在在进化中保持架构的稳定。

系统间的集成

系统间集成的工作常常会出现很多误解,因为系统间通常只靠接口交流,其它信息完全是隐藏的。未知带来了思维盲区和错误假设。我之前也写过博客感慨这类工作的不易(《关于接口开发和联调的一些感想 》)。
从集成角度分解开发内容时,一个重要目标是尽可能避免误解。这要求,
  • 接口要易于测试。这样可以增加接口的可信度,测试也有利于人们理解接口的功能。
  • 接口的表面复杂度要低。这意味着要对接口内部进行分解,将复杂度转移到下层,或者将某些副作用转移到接口之外的其它地方。

技术更新

我们时常需要使用新技术替换旧技术,这会为我们带来功能、性能或者KPI上的收益。从技术更新的角度考虑开发内容的分解时,就要把特定技术相关的部分分离,从而使得在不影响其它部分的情况下将技术变化,或者让新旧技术可以同时运行,逐步替换旧技术。

销售

有时,出于营销与销售的目的,程序的某些特性需要可以组合、开关、调节、修饰。这时,开发者需要从销售的角度思考开发内容的分解,做出可定制的程序,满足销售的目的。

投资

对于老板们来说,开发是一项针对未来的投资。他们预先支付薪水,接着期望开发者们交付的东西能帮助公司节约开支、获取收入。他们的心中可能存在一个简单公式,用来衡量程序开发工作的意义:

付给开发人员的钱可以被看做费用,那么,收入在哪里?分解开发内容时,要注意分解后的模块可以在一定的投资下产生价值,并且需要可以论证如果有后续投资的话可以产生更多价值。否则老板们可能会认为把开发人员裁掉才是更经济的选择。

组织架构

康威定律指出:

就像程序模块间存在信息传递的问题一样,不同的团队之间的沟通也会存在问题。程序的分解应该和组织形成匹配的关系,这样可以避免一些额外的工作和糟糕的结果。

上文提到过的为例,开源社区的开发成员之间只有松散的连接关系,因此,如果该项目的目标是让社区成员参与开发,那么就要尽可能地减少检查类之间的共享信息,选取第一种分解方式。如下图,

开发内容分解的9个角度-LMLPHP

反之,如果这完全是个内部项目,由单人开发,且完成后接口几乎不会发生变化,那么第二种分解方式可能更为合适。如下图,

开发内容分解的9个角度-LMLPHP

总结

本文介绍了开发内容分解的9个角度,这些角度在具体的实践中可能有重合或者冲突。从不同的角度考虑分解工作可以让我们产生不同的理解,更全面地审视自己的工作。但要注意的是分解并非越多越好,比如在设计自由度中我们提到分解导致的复杂度增加也会成为代价。要从整体考虑和观察开发内容,选取合适的角度。本文也没有涵盖所有的分解角度。

 
本文的主要思想来自于《系统架构》,结合了个人的一些开发实践,有兴趣了解更多的话可以看这本书。
 
 
 
 
 
 
 
 
 
06-11 00:29