编程模式:信息隐藏
信息可以分很多种类,但是从其效用性可以简单的划分两类:需要知道的和不需要知道的,而信息隐藏模式就是隐藏别人不需要知道的信息,所谓不需要知道,就是不知道也不影响使用,甚至知道之后反而形成束缚。
隐藏实现细节
我们需要隐藏哪些东西?试试多问自己这个问题,也许会给你带来一些不错的启发,如果你在犹豫一个东西是否隐藏,那么不妨先隐藏,直到它需要公开的时候再更改也不迟。
隐藏全局数据。共享全局数据是件危险的事,因为你需要明确知道所有潜在依赖者之间的相互影响,例如某一依赖者的访问,会影响另一依赖者的使用,所以最好的办法是,封装全局数据,提供间接的访问器,最好还能对语义进行抽象,保留可变化的空间。
隐藏顺序。最理想的接口调用方式,是不需要对调用接口做任何复杂的假设,其中顺序假设就是其一,例如你被要求必须先调用某个接口,再调用某个接口,这种调用方式对使用者是种认知负担,所以你最好能够隐藏顺序,或者是能从语义上给予显式的或强烈的暗示。
隐藏指针。指针在某些编程语言中是比较复杂的,为了降低犯错率,可以封装指针操作,把它隐藏起来。
降低复杂性
软件的首要任务是管理复杂性,由于人本身局部思维的限制,我们不可能一次性解决偌大的问题,就和吃牛排一样,要切成一片一片,慢慢品尝。那么降低复杂性和信息隐藏有什么关系呢?可以说信息隐藏就是为了隐藏复杂性,从而降低使用者所要面对的复杂性,但复杂性不会凭空消失,它只是被隐藏,我们要想驱动这些复杂性,就还得做些艺术性的处理,你也可以理解为代偿性处理。
名字至关重要。如果不能单从接口的名字想明白它是干什么用的,如何使用,或者说你必须翻阅文档,那么就说明这个接口还需改善。为什么取个好名字非常关键呢?因为它能给使用者带来启发和指引,如果使用者仅凭名字就能知道如何使用,对使用者来说是十分惬意的,对实现者来说也是轻松的,同时也代表了实现者对系统的深刻理解。命名标准在不同语言和不同团队或许有着完全不一样的版本,即使到目前为止,也没有足够通用的版本,但这不是最重要的,重要的是保持命名标准的一致性,例如你的常量采用全大写,使用下划线分隔单词,那么你就不要在同一系统的其他地方使用驼峰式命名法。其次,命名要容易理解,且具有一定的描述性,例如不要使用奇怪的缩写或者过于宽泛意义的单词。最后,可以适时考虑上下文,因为这可以让你的命名减少冗余性,以及更具简洁性。
提高确定性。如果编程是艺术,拥有无限的可能性,那么合格的且有天赋的程序员是稀有的,所以,不妨诚实的告诉自己,编程正在趋向工程化,趋向机械化,以及开始变得乏味。有个从日本流传过来的概念叫小确幸,小而确定的幸福,如果你的接口也能提供这种幸福感,相信你自己也会赏心悦目的。那么如何提高确定性呢?首先明白,更多的确定性意味着选择性减少,对使用者来说,就是减少假设,减少猜谜,减少混淆,而对实现者来说,就是要尽可能简单的表达,多利用常识和惯性。
保持一致的抽象。来自 Reddit 的一个程序员在喝醉酒后曾写道:“算法和数据结构确实重要,但不应该无限夸大,尤其是面试的时候。我没见过药剂师面试时,还要测试有机化学的细节。这个行业的面试过程有时候很糟糕。”如果抽象层次不在同一层级,就会面临十分混乱的局面,就好像你和好友聊天不在一个频道上,所以这个时候,我们必须分清楚事物的层级关系,比如我们在了解一个房屋的整体设计时,我们是不需要了解墙是怎样构建的,也就是说,在不同的视角下,我们需要主动限制我们所能看到的细节,这样做有助于增加抽象层级的一致性,从而降低思维负担。
提高可移植性
首先理解,所谓可移植性可以简单等价为代码的可复用性,而实现可移植性的关键在于有中立的抽象层,不偏袒任何一方实现,对使用者做适当的信息隐藏。
我们常说要封装变化,隔离变化,一旦这些变化对使用者隐藏后,使用者面对的将是精心设计的统一接口,而实现者则可使用策略模式,适时更换底层逻辑,从而与使用者形成契约式编程模式,达到解耦的目的,其中信息隐藏阻止了变化毫无节制的蔓延,变化被控制了,被封闭在有限的代码内,这对使用者来说是种莫大的幸福。
我们都曾梦想过,一次编写,随处运行,在语言层面,我们有运行时环境帮助屏蔽操作系统的差异,例如 Java 虚拟机,在细小编程中,我们有接口隐藏实现细节,从而降低对使用者的影响,无论是语言层面也好,还是细小编程也好,其本质在于信息隐藏帮助使用者摆脱了部分信息的束缚。
小结
信息隐藏模式在实际编程中随处可见,也许是太常见了,以至于我们常常忽视它的存在,但是在这里单独提出归纳总结,是为了保持对它的敏感性和启发性,从而指引我们发挥该模式的最大效用。总的来说,信息隐藏主要是隐藏实现细节,目的是为了降低复杂性和提高可移植性,从而提高使用者的幸福感。
公众号:hellomedivh
版权声明: 本文为 InfoQ 作者【Medivh Yang】的原创文章。
原文链接:【http://xie.infoq.cn/article/1583bf25f039a0a5ab9077807】。
本文遵守【CC-BY 4.0】协议,转载请保留原文出处及本版权声明。
评论