A Philosophy of Software Design读书笔记——模块应该有深度

管理复杂度的最重要的方法是每一次只需要面对一个小模块,这种方法被称为模块化设计。

模块化设计

整个系统被拆分成多个相对独立的模块。模块可以是类、子系统、服务。在理想情况下,模块间完全独立,开发某个模块时不需要感知到其他模块(不现实),一个系统的复杂度取决于这个系统中最复杂模块的复杂度。

不幸的是,模块间总有联系,一个模块总要调用别的模块,模块化设计的目标是尽可能的减少模块间的依赖性。

模块分成两个部分:接口和实现,接口是模块间需要感知的东西,接口定义了一个模块做什么以及如何使用它,实现保证了接口,编码一个模块时,需要知道这个模块的接口、实现以及其他模块的接口,但是不需要了解其他模块的实现。

只要有接口和现实的部分就是模块,一个好的工程实践是模块的接口要简单,实现可以复杂,这样有两个好处:调用者使用起来简单;设计者修改这些模块时,可以避免更改接口。

什么是接口

接口包含两部分:正式和非正式

正式:代码定义的,包括参数、返回值等

非正式:接口的功能,比如DeleteFile(const std::string& file_name),表示删除一个文件,甚至用注释说明这部分

抽象

抽象与模块化设计有关,抽象隐蔽细节,抽象以模块接口的方式展现,从使用者的角度去看,接口最重要,实现不重要,在设计接口时,需要站在使用者的角度去看

抽象有两个错误表现:1、展现了不必要的细节,导致使用者认知放大;2、隐蔽了重要的细节,导致使用者晦涩难懂。所以抽象设计起来并不是越简单越好,需要深刻理解这个抽象,然后仅仅包含重要的信息,使得使用者仅仅看到抽象之后,就能或者到这个模块的所有需要获知的信息。

例子:文件系统,如何在磁盘上布局数据,不需要对使用者暴露,但是page cache是需要对用户暴露的,所以提供了flush接口

深度模块

最好的模块时提供很好的功能,但是保持简单的接口。(最简单的,从代码量上看,实现的代码很多,但是接口,包括注释的行数很少)

浅度模块

方法类(一个方法一个类?)

类要深,不一定要小,也不是说类越多越好,比如建议:一个方法如果超过多少行,就要被拆分,这个建议不一定对,可能会增加系统的复杂度。(要根据类或者模块要提供的功能来实现,要切切实实的提供功能相关的接口,至于功能的实现,只要隐蔽的好,不会增加复杂度)

例子:Java和Unix IO对比

java的编码风格提供类越多越好,比如打开文件序列化对象需要三步,违反了对于常见用法提供的接口越简单越好。

好的设计应该和Unix IO一样。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值