modules should be deep
管理系统复杂性最重要的技巧就是,很好地设计系统,使得开发人员在任何时候都只需要面对整体复杂性的一部分,这种设计就是模块设计。
模块设计
在模块设计中,整个系统被划分成多个相对独立的模块。理想情况下,每个模块之间是完全独立的,开发其中一个模块,完全不需要了解其他模块。在这种情况下,整个系统的复杂性由最复杂的模块决定。
但是,现实情况是,每个模块之间肯定会存在方法的调用,因此必须了解其他模块,当一个模块发生改变时,另外一个模块也需要跟着改变,比如一个方法的参数进行了改变,调用该参数的模块也需要跟着改变,因此,模块设计的目标就是减少模块之间的依赖。
模块主要由两个部分组成:接口和实现。接口告诉其他其他当前模块能干嘛,实现告诉其他模块怎么做。
好的模块是接口远比实现简单。这样做主要由两个好处:
- 减少了该模块对外暴露的复杂性
- 如果一个模块虽然进行了修改,但是没有修改接口,那么其他模块就不会受此次修改的影响
接口中有什么
接口中主要包含两部分信息:正式信息和非正式信息
正式信息
正式信息就是显式地在代码中定义的,这些信息会受到变成语言的校验。正式的信息主要包括公共方法的签名和公共变量的名称和类型。
非正式信息
非正式信息不会受到编程语言的校验,比如根据输入参数删除了某个文件,比如方法的使用是有限制的(该方法只能在另外一个方法调用之后才能调用)
非正式信息只能使用注释来阐明。
抽象
抽象是一个实体的简化视图,省略掉了不重要的部分。抽象使我们可以更加方便地使用抽象的东西。
在模块编程中,模块以接口的形式来提供抽象。
在抽象中最重要的定义就是不重要,一个接口忽略越多的不重要信息,那么该接口设计的就越好。
错误的接口设计主要有两种:
- 包含一些不重要的信息,这样会使接口变得复杂
- 忽略了一些重要的信息,开发人员看着接口,无法了解到调用该接口所必须的所有信息
接口设计的关键是了解什么是重要的,寻找能够最小化重要信息的设计
举个例子,文件系统的设计,屏蔽掉了在存储设备上选择物理块的机制,这些信息对于文件系统的使用者来说是不重要的。另一方面,有些信息就很重要,比如常见的文件系统都会将数据先写入到主存中,之后再刷写到磁盘中,对于一些应用,比如数据库,数据什么时候刷写到磁盘上就很重要,因为如果数据刷写到磁盘之后,数据库系统就可以保证,即使系统崩溃,数据也不会丢失。所以,刷写策略就必须通过接口暴露给用户。
深模块
最好的模块,拥有简单的接口,但是却具有强大的功能。

将模块想象成一个矩形,矩形的面积和它具有的功能强大性成正比,矩形的顶部边代表模块的接口,边的长度代表接口的复杂度,将复杂的实现屏蔽掉,将简单的抽象暴露给用户。
浅模块
浅模块和深模块相对,它具有的接口相对于它提供的功能来说可能更加复杂。

古典
但是如今的编程领域并不推崇深模块,如今的编程理念是模块应该小而不是深。人们经常被告诉应当将大的类拆分成几个小的类。但是这种理念会有问题,在这种理念下的系统,如果你想要更多的功能,就需要引入更多的类,因此会增加系统的复杂性。小的类并不会提供太多的功能,所以整个系统需要很多小的类
例子
java中的文件操作就深受古典编程理念的影响,为了打开一个文件来读取其中的内容,需要如下三步
FileInputStream fileStream =
new FileInputStream(fileName);
BufferedInputStream bufferedStream =
new BufferedInputStream(fileStream);
ObjectInputStream objectStream =
new ObjectInputStream(bufferedStream);
FileInputStream只具备基本的io,无法进行缓冲,也无法读取序列化对象
BufferdInputStream添加了缓冲的功能,ObjectInputStream则添加了读取序列化对象的功能;上面创建的三个对象,在后续的使用中,只会使用objectStream,而另外两个对象在创建之后就不会再使用了
其中最烦人的是,如果忘记使用bufferedinputStream,那么就不会使用到缓冲的功能,从而造成读取速度较慢;一些人认为应当将缓冲功能分离,让使用者决定是否使用。但是,好的接口设计,应当使普通常见情况的接口越简单越好。
几乎每一个使用文件io的人,都会想要使用到缓冲的功能,因此应该默认支持缓冲
结论
通过将接口和实现分离,可以将实现的复杂度隐藏,接口的使用者只需要了解接口提供的抽象即可,不需要了解实现;同时在设计接口或者模块的时候,应该设计深接口或者深模块
本文探讨了模块设计在管理系统复杂性中的作用,强调了深模块的概念,即拥有简单接口但功能强大的模块设计,对比了深模块与浅模块的区别,以及现代编程理念中的小模块设计的局限性。
217

被折叠的 条评论
为什么被折叠?



