Feeds:
Posts
Comments

Posts Tagged ‘结构’

软件之形

软件有形状吗?我觉得有。从大的方面讲,软件有外在形状与内在形状之分。外在形状是用户界面,而内在形状是代码和各种结构图。本文只讨论内在形状。

如果有一种特殊的望远镜能让我们观察软件,那当镜头拉到最近时,我们看到的是代码;把镜头推远一点,我们看到的是程序结构图或类结构图;再远一点是模块图;推到最远是总体架构图。

软件最直观的形状是代码的形状。虽然世上没有统一的代码规范,但代码确有好看难看之分。难看的代码或挤成一团、密不透风,或充斥多余空行空格,或缩进(indent)毫无规律,或毫无注释,或注释喧宾夺主、画蛇添足;命名方式一会儿用PASCAL命名法,一会儿用CAMAL命名法,一会儿用HANGARIAN命名法,一会儿用下横杠(underscore)。难看的代码让人不忍卒读。好的代码总是简洁、清爽、疏密有致,该加空行加空行,该加空格加空格,该加注释加注释,该缩进缩进(但缩进太深也不好)。好的代码总是风格统一,类、函数、变量都有统一的命名规范。好的代码让人读来如沐春风。

比代码更抽象更高一级的形状是程序结构图或类结构图。在结构化设计方法中,程序结构图是设计阶段的成果,描述程序之间的调用关系。从程序结构图的形状大致可以看出设计的好坏。Edward Yourdon与Larry L. Constantine在他们合著的《结构化设计》中指出,他们从大量的观察中发现大多数设计良好的系统,其程序结构图的形状都大致像清真寺的穹顶一样:最高层和最底层的模块都相当较少,而中间层的模块相对较多;高层的模块具有较高的扇出,底层的模块具有较高的扇入。

尽管结构化程序设计已逐渐被面向对象程序设计取代,但结构化程序设计的一些准则依然适用,如信息隐蔽、函数和模块的聚合度要高、函数间与模块间的耦合度要低等。而且在设计具有复杂数据流的系统时,结构化程序设计方法仍值得借鉴。

在面向对象程序设计方法中,类结构图是设计阶段的重要结果。从类结构图中又能看出什么呢?首先,类之间的关联切勿过多,最好是单向,尤其要避免循环关联。根据领域驱动设计(Domain Driven Design)方法,类要分成不同的聚集体(Aggregate),聚集体之外的类只能与聚集体的根(Aggregate Root)关联。这样能有效地减少类之间的关联。另外,类的继承关系既不要宽而浅(broad and shallow),也不要过于窄而深(narrow and deep)。一个基类有20个直接子类固然不好,一个有20层深而每个类最多只有一个子类的设计也不可取。动物分类图是一个很好的例子,它既不太宽也不太窄、既不太浅也不太深。

结构图只是软件形状的一种形式。通过不同的“滤镜”,我们可以看到软件不同形式的形状。人们不断发明新方法用形象化的方式揭示软件内部的特性。如Red Gate的.NET Reflector有一个插件CodeMetrics能分析程序的各种内部特性,并用TreeMap显示出来,如下图。通过此图我们可以看出各个类的代码量、复杂度等,看他们是否超出了规定的界限,从而决定如何改善设计。

Figure 1 Code Metrics

围棋有好形愚形之分。棋子挤成一团、密不透风、子力重复的是愚形。棋子疏密有致、距离恰到好处的是好形。软件也颇有相似之处。从代码角度讲,标识符之间、标识符与操作符之间要有空格(括号除外),逻辑片段之间要有空行,不要有重复代码。从结构角度讲,函数之间、模块之间耦合要低。

比程序结构图和类结构图更高一层的是模块结构图,强调的是依赖关系和接口。依赖关系要越少越好,接口要越简单越好。避免循环依赖关系。其目的是控制系统的复杂度,对复杂的系统分而治之。

不识庐山真面目,只缘身在此山中。要真正了解一个软件的全貌,还要把镜头更推远一点,了解其总体架构。

现在,层状结构日益流行。层状结构的主要目的也是为了控制系统的复杂度。层次之间的依赖关系是单向的。层次高的依赖层次低的,层次低的不可以反过来依赖层次高的。下图是Domain Driven Design所推荐的系统结构,其核心是领域层(Domain Layer),再上一层是应用层,最高层是用户界面层。每一层都有不同的基础结构(Infrastructure)支持。层次之间分工明确。

Figure 2 Domain Driven Design推荐的层状结构 (http://dddsample.sourceforge.net/architecture.html

Jeffrey Palermo更进一步提出了洋葱结构(Onion Architecture):把水平的层状图变成圆形层状图,把基础结构层推到最外层,领域层成为系统核心。这与地球与细胞的内部结构图何其相像。

Figure 3 Onion Architecture (http://jeffreypalermo.com/blog/the-onion-architecture-part-2/)

从不同层次、不同角度我们能看到软件的不同形状。从这些形状中,我们能大致看出软件的质量。总体来说,好的形状简洁、平衡、统一,能给人以美感。跟软件之形同样重要或更重要的是软件之神,即设计原则(Design Principles)和设计理念(Design Philosophy或Design Considerations)。真正好的软件当形神兼备。

Advertisements

Read Full Post »