KISS(保持简单)
大多数系统在保持简单而不复杂的情况下运作得最好。
为什么:
- 代码越少,编写时间越短,bug越少,修改起来也更容易。
- 简单即是至臻的优雅。
- 看起来完美并不是在没有东西可添加时实现的,而是在没有东西可删减时实现的。
资源:
YAGNI(你不会需要它)
YAGNI代表“你不会需要它”,在必要之前不要实现它。
为什么:
- 任何只为明天可能需要的功能而做的工作,意味着在当前迭代中失去了完成其他功能的努力。
- 它会导致代码膨胀,软件变得更大更复杂。
如何:
- 只有在真正需要时才实现功能,而不是仅仅预见到需要它们时才实现。
资源:
做最简单可能的事情
为什么:
- 只有真正解决实际问题的简单事情才能取得真正的进展。
如何:
- 问自己:“最简单可能的事情是什么?”
资源:
关注点分离
关注点分离是一种将计算机程序分成不同部分的设计原则,以便每个部分都涉及一个不同的关注点。
为什么:
- 简化软件应用程序的开发和维护。
- 当关注点良好分离时,可以独立地重用、开发和更新各个部分。
如何:
- 将程序功能分解为尽可能少重叠的单独模块。
资源:
保持DRY(不要重复自己)
为什么:
- 重复(无意或有意的重复)可能导致维护困难、代码重构问题和逻辑矛盾。
- 对系统的任何单个元素进行修改不需要改变其他逻辑上无关的元素。
如何:
- 将业务规则、长表达式、if语句、数学公式、元数据等放在一个地方。
资源:
为维护者编写代码
为什么:
- 维护是任何项目中最昂贵的阶段。
如何:
- 成为维护者。
- 编写代码和注释时,要以维护代码的人是一个知道您住在哪里的暴力疯子为前提。
- 始终以编写代码和注释的方式,使得稍微低级的人可以愉快地阅读和学习它。
资源:
避免过早优化
为什么:
- 预先不知道瓶颈在哪里。
- 优化后,阅读代码可能更困难,从而使维护更加困难。
如何:
- 使其正常工作,使其正确,使其快速
- 在需要时再进行优化,仅在进行性能分析并发现瓶颈后再进行优化。
资源:
最小化耦合
为什么:
- 一个模块的更改通常会导致其他模块的连锁反应更改。
- 由于增加了模块间的依赖关系,模块的组装可能需要更多的工作和/或时间。
- 由于必须包含依赖模块,某个特定模块可能更难被重用和/或测试。
- 开发人员可能害怕更改代码,因为他们不确定可能受到什么影响。
如何:
- 消除、最小化和减少必要关系的复杂性。
资源:
迪米特法则
为什么:
- 这通常会加强耦合度。
- 它可能会暴露太多的实现细节。
如何:
- 对象的方法只能调用以下方法:
- 对象本身的方法。
- 方法的参数。
- 在方法中创建的任何对象。
- 对象的直接属性/字段。
资源:
组合优于继承
为什么:
- 类之间的耦合度较低。
- 使用继承,子类容易做出假设,并且违反了LSP。
如何:
- 测试LSP(可替换性)以决定何时继承。
- 当存在“具有”(或“使用”)关系时使用组合,当存在“是”关系时使用继承。
资源:
正交性
关于正交性:
- 正交性的基本思想是在系统中不相关的概念之间不应该有关联。
- 它与简单性有关;设计的正交性越高,例外情况越少。这使得学习、阅读和编写编程语言中的程序更容易。正交特性的含义与上下文无关;关键参数是对称性和一致性。
资源:
稳健性原则
为什么:
- 为了能够发展服务,您需要确保提供者可以进行更改以支持新的需求,同时对现有客户端的破坏最小。
如何:
- 发送命令或数据到其他计算机(或同一台计算机上的其他程序)的代码应完全符合规范,但接收输入的代码应接受非符合规范的输入,只要意义清楚。
资源:
控制反转
为什么:
- 控制反转用于增强程序的模块化并使其可扩展。
- 将任务的执行与实现分离。
- 将模块专注于其设计的任务。
- 使模块不依赖于其他系统如何执行其工作,而是依赖于契约。
- 在替换模块时防止副作用。
如何:
- 使用工厂模式
- 使用服务定位器模式
- 使用依赖注入
- 使用上下文查找
- 使用模板方法模式
- 使用策略模式
资源:
最大化内聚性
为什么:
- 理解模块变得更加困难。
- 维护系统变得更加困难,因为域中的逻辑变化会影响多个模块,并且因为一个模块的更改需要相关模块的更改。
- 重用模块变得更加困难,因为大多数应用程序不需要模块提供的随机操作集。
如何:
- 将共享单一责任的相关功能分组(例如,在一个类中)。
资源:
Liskov替换原则
LSP关注对象的预期行为:
- 程序中的对象应该可以替换为其子类型的实例,而不会改变程序的正确性。
资源:
开闭原则
为什么:
- 通过最小化对现有代码的更改来提高可维护性和稳定性。
如何:
- 编写可扩展的类(与可以修改的类相对)。
- 仅公开需要更改的可移动部分,隐藏其他所有内容。
资源:
单一责任原则
为什么:
- 可维护性:只有在一个模块或类中需要进行修改。
如何:
- 应用Curly's Law。
资源:
隐藏实现细节
为什么:
- 当实现发生变化时,接口客户端使用的接口不需要更改。
如何:
- 最小化类和成员的可访问性。
- 不要在公共环境中公开成员数据。
- 避免将私有实现细节放入类的接口中。
- 减少耦合以隐藏更多的实现细节。
资源:
Curly's Law(卡利法则)
Curly's Law是关于为任何特定的代码目标选择一个单一、明确定义的目标的法则:只做一件事。
资源:
封装变化
为什么:
- 在发生变化时最小化所需的修改。
如何:
- 封装可变概念在API后面。
- 可能将可变概念分离到其自己的模块中。
资源:
接口隔离原则
为什么:
- 如果一个类实现了不需要的方法,调用方需要知道该类的方法实现。例如,如果一个类实现了一个方法,但只是简单地抛出异常,那么调用方将需要知道这个方法实际上不应该被调用。
如何:
- 避免臃肿的接口。类不应该被迫实现违反单一责任原则的方法。
资源:
童子军法则
美国童子军有一个简单的规则,我们可以应用到我们的职业中:“离开营地时比你来时干净”。童子军法则表示,我们应该始终比我们找到的代码更加清晰。
为什么:
- 当对现有代码库进行更改时,代码质量往往会下降,累积技术债务。遵循童子军法则,我们应该在每次提交时关注代码质量。通过持续重构,无论规模大小,抵制技术债务。
如何:
- 确保每次提交都不会降低代码库的质量。
- 每当有人发现某个代码不够清晰时,都应该抓住机会立即修复。
资源:
命令查询分离
命令查询分离原则指出,每个方法应该是一个执行操作的命令或返回数据给调用者的查询,但不应同时具备两者。提问不应修改答案。
为什么:
- 通过明确将方法分为查询和命令,程序员可以在不了解每个方法的实现细节的情况下编写代码。
如何:
- 将每个方法实现为查询或命令。
- 应用命名约定来暗示方法是查询还是命令。
资源:
墨菲定律
任何可能出错的事情终将出错。
资源:
布鲁克斯定律
在一个已经延期的软件项目上增加人手只会使项目进一步延期。
资源:
林纳斯定律
只要有足够多的眼睛,所有的错误都是肤浅的。
资源: