1. 软件设计目标
<strong>帮助其它人</strong>,做与软件相关的决策时,指导法则就是判断能够提供什么样的帮助。一个人写出优秀软件的能力,完全取决于他在多大程度上理解了“帮助其它人”的思想。
- 确保软件能够提尽可能多的帮助;
- 确保软件能够持续提供尽可能多的帮助;
- 设计程序员能尽可能容易开发和维护的软件系统,这样的系统才能为用户提供尽可能多的帮助,而且能持续提供尽可能多的帮助;
2. 关于未来
1.相比降低实现成本,降低维护成本更加重要
2.设计质量的好坏,正比于该系统未来能持续帮助他人时间的长度
通俗点就是,如果你的软件只能在未来几小时内提供帮助,就不需要花太多的功夫去设计,如果需要在未来10年内都能派上用场,就需要花很多精力去设计。
3.所以,软件设计时最关注的应该是未来。但是,未来的某些事情,是我们所不知道的。程序员犯的最常见也是最严重的错误,就是在其实不知道未来的情况下去预测未来。
在软件设计时,可以根据已知的信息去做某些决策,目的是为了创造更好的未来(提升价值、降低维护成本),而不必预测未来究竟发生什么具体的事情。
3. 关于变化
程序存在的时间越久,它的某个部分需要变化的可能性就越高;
关键在于,我们并不需要去预测有什么变化 ,我们知道的是,变化必然会发生,程序应该<strong>保证尽可能合理的灵活性</strong>。
回预某个特定文件修改历史,问问自己,最初写这个文件时,你能预测到这些变化吗?是否一开始写好就能够减轻后期的工作量。总的来说,就是尝试理解每次修改,看看能否从中得到一些关于软件开发的新收获。
软件设计三大误区
- 编写不必要的代码
不要编写不需要的代码,并且要删除没有用到的代码。- 代码难以修改(僵化设计)
* 对未来做太多假设
* 不仔细设计就开始编码
* 设计程序时,应当根据现在知道的确切的需求,而不是我们认为未来会出现的需求。
- 过分追求通用;
- 仅仅根据目前确知的需求来考虑通用
- 如果设计让事情变复杂而不是变简单,就是在做过度工程
渐进式设计
渐进式开发
4. 缺陷和设计
最好的设计,就是能适应外界尽可能多的变化,而软件自身的变化要尽可能的少
- 永远不要"修正"任何东西,除非它真是一个问题,而且有证据表明问题确实存在;
- 避免重复
理想情况下,任何系统里的任何信息,都应当只存在一次或只存在一个地方;让各处的代码可以“使用Use”、“调用Call”、“包含Include”已有的其它代码;
5. 简洁
软件的任何一部分越简单,维护难度越小,成本越低。
简洁是指某部分的代码,而不是指整个系统。
- 简洁是相对的
- 简洁到什么程度?傻子也能看懂
- 保持一致
如果在一个地方采取了某种规则,就应当在其它每个地方都遵守这种规则,如变量命名方式等。 - 可读性
- 空白:字符、代码行之间留有合适的空白
- 命名:名字应该足够长,能完整表达其意义或描述其功能,但不能太长影响阅读
- 注释:程序简单的不能再简单的时候,再添加注释
6. 复杂性
以下情况会增加复杂性:
- 扩展软件的用途:应当绝对禁止这样做
- 新增程序员: 除非是高高手
- 做无谓的改变:需求变化、设计变化、代码变化等,谨慎决策
- 困于糟糕的技术:先前采用的技术不能灵活地适应未来的需求
- 理解错误:越不理解自己的工作,就越容易设计出复杂的系统
- 糟糕的设计或不做设计:指的是“没有为变化做设计”
- 重新发明轮子:不要什么都自力更生,使用成熟的轮子
复杂性及错误的解决办法
需要反问的问题是:真正要解决的问题是什么?
-
问题复杂
解法不一定复杂;大多数麻烦的设计问题,都可以用在纸上画图或写出来的办法中找到答案。 - 应对复杂性
- 如果系统中某个部分太过复杂,有个好办法可以解决:把它分解成几个独立的小部分,逐步重新设计;每次修改都应该足够小,这样可以放心动手,不会让事情变得更复杂。
- 如果遇到不可解决的复杂性,在程序外面妥善包装上一层,让其它程序员更容易理解和使用
7. 测试
测试法则:
- 对软件行为的了解程度,等于真正测试它的程度。测试程度包括:软件有多个方面曾经测试过,上次测试是多久以前,在多少不同的环境下经过测试等。
- 必须保证测试是准确的,它的行为完全符合预期,测试结果必须有效。