设计原则
五大设计原则:SOLID
一、单一职责原则
SRP
任何一个软件模块都应该有且仅有一个被修改的原因,也可以说任何一个软件模块都应该只对某一类行为负责。
反例
多人为了不同的目的修改了同一份源代码,这就很容易出现问题。
解决办法
可以抽象出公共类,用门面模式(Facade)不同的业务再做不同扩展。
总结
单一职责原则主要讨论的是函数和类之间的关系——但是它在两个谈论层面上会以不同的形式出现。
在组件层面,我们可以将其称为共同闭包原则(Common Closure Principle)。在软件架构层面,它则是用于奠定架构边界的变更轴心。
二、开闭原则
OCP
设计良好的软件应该易于扩展,同时抗拒修改。
换句话说,一个设计良好的软件在不需要修改的前提下就可以轻易扩展。这也是我们研究软件架构的根本目的。
尽管大部分软件设计师都已经认可了OCP是设计类与模块时的重要原则,但是在软件架构层面,这项原则意义则更为重大。
应用实验
一个好的软件架构师会努力将旧代码的修改需求量降至最小,甚至为0。如何做到呢,我们可以先将满足不同需求的代码分组(即SRP),然后再来调整这些分组之间的依赖关系(即DIP)。
分层架构,将代码分成不同的层次。即将整个程序进程划分成一系列的类,然后再将这些类分成不同的组件,然后用依赖反转控制它们之间的依赖关系,使低层组件依赖高层组件,这样高阶层组件就不会因为低阶组件被修改而受到影响了。
依赖原则:低层应该依赖高层,高层不应该依赖低层,实现应该依赖抽象,抽象不应该依赖具体实现;单向依赖。
总结
OCP是我们进行系统设计的主导原则,主要目标是让系统易于扩展,同时限制每次修改所影响的范围。
实现方式是通过将系统划分为一系列组件,并且将这些组件间的依赖关系按层次结构进行组织,使得高阶组件不会因低阶组件的改动而受到影响
三、里氏替换原则
LSP
任何一个使用父类(接口)的地方都应该能用子类(实现)替换。
总结
LSP可以且应该被应用于软件架构层面,因为一旦违背了可替换性,该系统架构就不得不为此添加大量复杂的应对机制。
四、接口隔离原则
ISP
一个类(方法)不应该依赖与它无关的类(方法)
ISP与软件架构
任何层次的软件设计如果依赖于不需要的东西,都会是有害的。
从源代码层次来说,这样的依赖关系会导致不必要的重新编译和重新部署。对更高层次的软件架构设计来说,问题也是类似的。
总结
任何层次的软件设计如果依赖了它并不需要的东西,就会带来意料之外的麻烦。
五、依赖反转原则
DIP
通过依赖接口而非具体实现,可以使控制流的方向与源代码依赖关系的方向正好相反。
依赖反转原则,主要想告诉我们:如果想要设计一个灵活的系统,在源码层次的依赖关系中就应该多引用抽象类型(接口),而非具体实现。
稳定的抽象层
把依赖反转这条设计原则当做标准严格执行是不现实的,因为软件系统在实际构造过程中不可避免地需要依赖到一些具体实现。只要依赖的具体实现是稳定的也没有问题。
当我们修改接口时,肯定要去修改实现。反过来我们修改实现时,却不需要修改接口。所以我们说接口比实现更稳定。
实践应用
优秀的软件设计师和架构师会花费很大精力来设计接口,以减少未来对其进行修改。毕竟争取在不修改接口的情况下为软件增加新的功能是软件设计的基础常识。
也就是说,如果想要在软件架构设计上追求稳定,就应该多使用稳定的抽象接口,少依赖多变的具体实现。
一些编码守则:
- 在代码中多使用抽象接口,尽量避免使用那些多变的具体实现类。
- 不要在具体实现类上创建衍生类(少继承具体实现类)。
- 不要覆盖包含具体实现的函数。
- 应避免在代码中写入与任何具体实现相关的名字,或者是其它容易变动的事物的名字。
工厂模式
基本在所有的编程语言中,创建对象的操作都避免不了需要在源代码层次上依赖对象的具体实现。我们可以用抽象工厂模式来解决这个源代码依赖的问题。
我们不可能完全消除违反DIP的情况,通常只需要把它们集中于少部分的具体实现组件中,将其与系统的其它部分隔离即可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构