SOLID 五大设计原则,+ 迪米特法则,组成编程设计的六大原则。
1:单一职责原则 SRP
比较容易误解的地方,认为每个模块都应该只做一件事。这也算是一个设计原则,确保一个函数只完成一个功能,但这只是一个面相底层实现细节的设计原则,不是SRP的全部。
合理的说法是,任何一个软件模块都应该只对某一类行为者负责。在类的设计上,区分好行为者的角色,减少依赖。
软件模块可以指一组紧密相关的函数和数据结构。
单一职责原则,主要讨论的是函数和类之间的关系,在组件层面,我们可以称之为 共同闭包原则,在软件架构层面,它则是奠定架构边界的变更轴心。
2:开闭原则 OCP
良好的设计应该易于扩展,同时抗拒修改,限制其每次修改所影响的范围。
实现方式是通过将系统划分为一系列组件,并将这些组件间的依赖关系按层级结构进行组织,使得高阶组件不会因低阶组件被修改而受到影响。
3:里氏替换原则 LSP。
子类可以替换父类的功能,也可以复写父类的方法。
4:接口隔离原则ISP
image.png此种设计方式,不太合理。如使用Java静态类型语言编写,User1虽然不需要调用op2 op3a,但在源码层次上也与他们形成依赖关系,这种依赖意味着我们对ops代码中op2 所做的任何修改,即使不会影响到user1的功能,也会导致它需要被重新编译和部署。
所以需要接口隔离。
任何层次的软件设计如果依赖了它并不需要的东西,就会带来意料之外的麻烦。
5:依赖反转原则DIP
如果想要设计一个灵活的系统,在源代码层次的依赖关系中就应该引用抽象类型,而非具体实现。
也就是说在Java这类静态类型语言中,在使用use import include 时,应该尽量只引入那些包含接口,抽象类或者其他抽象类型声明的源文件,不应该引用具体的实现。
依赖倒置原则定义
1、上层模块不应该依赖底层模块,它们都应该依赖于抽象。
2、抽象不应该依赖于细节,细节应该依赖于抽象。
首先,这个原则听起来很像是“针对接口编程,不针对现实编程”,不是吗?的确很相似,然而这里更强调“抽象”。
依赖倒置原则,究竟倒置在哪里?
在依赖倒置原则中的倒置指的是和一般OO设计的思考方式完全相反。
举个例子,现在你需要实现一个比萨店,你第一件想到的事情是什么?我想到的是一个比萨店,里面有很多具体的比萨,如:芝士比萨、素食比萨、海鲜比萨……
比萨店是上层模块,比萨是下层模块,如果把比萨店和它依赖的对象画成一张图,看起来是这样:
正常依赖图没错!先从顶端开始,然后往下到具体类,但是,正如你看到的你不想让比萨店理会这些具体类,要不然比萨店将全都依赖这些具体类。现在“倒置”你的想法……别从上层模块比萨店开始思考,而是从下层模块比萨开始,然后想想看能抽象化些什么。你可能会想到,芝士比萨、素食比萨、海鲜比萨都是比萨,所以它们应该共享一个Pizza接口。对了,你想要抽象化一个Pizza。好,现在回头重新思考如何设计比萨店。
依赖倒置后的图图一的依赖箭头都是从上往下的,图二的箭头出现了从下往上,依赖关系确实“倒置”了
另外,此例子也很好的解释了“上层模块不应该依赖底层模块,它们都应该依赖于抽象。”,在最开始的设计中,高层模块PizzaStroe直接依赖低层模块(各种具体的Pizaa),调整设计后,高层模块和低层模块都依赖于抽象(Pizza)。
网友评论