最近又开始读《代码大全2》。

   《代2》中有一个观点贯彻全书:软件工程的本质即是管理复杂度。

     书中将复杂度分为两大类,一种是本质复杂度,一种是偶然复杂度。

     本质复杂度可以理解为项目的问题域本身,这种复杂度是可以预期的。

     偶然复杂度可以理解为项目生产的过程遇到的相关问题,比如开发工具的效率,团队内部的交流效率。

    我们应以何种态度与方法面对这两种复杂度?

    尽量避免与减少偶然复杂度。

   对本质复杂度,要采用各种方法进行控制。以下列出了几种方法:

  1,模块化。

  2,限制可以进行交流的模块。

  3,模块间的连接要尽可能少。 

  4,接口要很好的抽象化,使得完全不需要了解内部实现的细节

模块化实际上就是将问题进行分解,使得某一时刻可以只关注于某一问题。模块的规模可以是包或者是类。

 3指模块间通信的接口要尽可能的少,能用1个接口解决两个模块间的通信,就不要用2个。

一个模块的接口越简洁,就会使得需要与这个模块合作的模块的复杂度越低。

  5,掩藏变化。

  掩藏变化的好处就是可以避免让变化散步于代码的各处,减少改编代码的复杂度。

 比如如果你程序中需要用到一个id的数据,而id的类型可能会存在变化,那么这种情况下

int id;这种方式就会令以后的改变很复杂。

而typedef int IdType; IdType id;这种方式就会令改变很容易。

另一种常见的情况可能是,你希望你的代码能够跨平台编译,或者在移植到不同的平台的时候只需要很少的改变。

在这种情况下,变化的因素就是不同平台的系统api。这些api所实现的功能相似但名称和调用方式有所不同。

我们可以再api的调用上抽象出一个层次,我们的其他模块与我们的抽象层次交互而不直接与底层系统交互,这样

在移植的时候只需要更改抽象层次与系统api之间的交互即可,或者添加新的子类。我们项目中的其他的部分就不需要更改。

上面的例子也揭示了一个道理,就是把预期到会变化的部分可以集中出来在一个模块内并提供上层的抽象,这样就能很好的降低复杂度。

 关于复杂度管理应该还有很多东西要学,以后在项目中应该会有更多体会。