面向对象的设计原则
针对笔者本人,在设计系统时,总是会忘记这些原则,所以特地整理资料
面向对象的设计原则
“原则”,英文译为:Principle,而对于原则一词的解释:原则是能够在相似场景下反复运用的一套概念,有别于具体问题的狭义回答,即智者见智,对原则理解越透彻,则越能明白原则对你的影响有多大,而在软件领域,特别是面向对象的领域里,面向对象的设计原则更是基础中的基础,而这些原则的出现便是许多人的得出来的总结,
面向对象设计的设计原则不是必须要遵守的,而作为一个优秀的软件,想必都会有遵循这些原则,我特地指出这些原则不是必须的,但是,而说到原则,SOLID(单一功能、开闭原则、里氏替换、接口隔离以及依赖反转)所包含的原则是通过引发编程者进行软件源代码的代码重构进行软件的代码异味清扫,从而使得软件清晰可读以及可扩展时可以应用的指南,所以我认为原则应该在软件的设计中不断地使用,而成为一种条件反射。
从图中看到每个原则的说明都是比较简单的,但原则是通过实践才能体会出它的重要性
SOLID(单一功能、开闭原则、里氏替换、接口隔离以及依赖反转)是由罗伯特·C·马丁在21世纪早期 引入的记忆术首字母缩略字
1.单一职责原则:SRP--Single-Responsibility Principle
就一个类而言,应该只专注于做一件事和仅有一个引起它变化的原因,马丁把功能(职责)定义为:“改变的原因”,并且总结出一个类或者模块应该有且只有一个改变的原因
每个类应该都有单一的功能(职责),而且由类完全封装起来,即解耦,注意功能并不代表这个类只有一个方法或者函数,保持一个类专注于单一功能点上的一个重要的原因是,它会使得类更加的健壮,而在面向对象原则上的引申,将职责定义为引起变化的原因,以提高内聚性来减少引起变化的原因。职责过多,可能引起它变化的原因就越多,这将导致职责依赖,相互之间就产生影响,从而大大损伤其内聚性和耦合度。
SRP为最简单的原则,也是最难运用好的原则
2.开闭原则:OCP--Open-Closed Principle
对扩展开发,对修改封闭,抽象化是面向对象设计的关键
当已有的软件需要增加一个新的功能时,不需要在已有的抽象层中进行修改,只需要扩展已有的实现层,核心思想便是面向抽象编程,在面向对象的编程中,抽象层和接口规定了类的的特征,作为一个抽象层,然后进行修改封闭,而继承了抽象层的具体类实现了改变系统的行为,从而满足扩展
3.里氏替换原则:LSP--Liskov Substitution Principle
派生类(子类)对象能够替换其基类(超类)对象被使用
里氏替换原则即继承机制的基础,在任何父类出现的地方都可以用他的子类来替代,子类必须完全覆盖父类的方法,此原则反过来则是不成立的,子类可以替换基类,但是基类不一定能替换子类,子类的所有方法必须在父类中声明,或子类必须实现父类中声明的所有方法
4.接口隔离原则:ISP--Interface Segregation Principle
接口隔离原则(ISP)拆分非常庞大臃肿的接口成为更小的和更具体的接口
提供尽可能小的单独接口,而不要提供大的总接口,在面向对象设计中,接口(interface)提供了便于代码在概念上解释的抽象层,并建立了避免依赖的一个屏障。
分离接口的两种实现方法:
1.使用委托分离接口。(Separation through Delegation)
2.使用多重继承分离接口。(Separation through Multiple Inheritance)
5.依赖反转原则:DIP--Dependency inversion principle
抽象不应当依赖于细节;细节应当依赖于抽象
该原则规定:
- 高层次的模块不应该依赖于低层次的模块,两者都应该依赖于抽象接口。
- 抽象接口不应该依赖于具体实现。而具体实现则应该依赖于抽象接口。
采用依赖倒置原则可以减少类间的耦合性,当两个模块之间存在紧密的耦合关系时,最好的方法就是分离接口和实现:在依赖之间定义一个抽象的接口使得高层模块调用接口,而底层模块实现接口的定义,以此来有效控制耦合关系,达到依赖于抽象的设计目标,我们先了解传统的应用架构中,低层次的组件设计用于被高层次的组件使用。在这种结构下,高层次的组件直接依赖于低层次的组件去实现一些任务。这种对于低层次组件的依赖限制了高层次组件被重用的可行性。
依赖倒置原则就是要求调用者和被调用者都依赖抽象,这样两者没有直接的关联和接触,在变动的时候,一方的变动不会影响另一方的变动。
参考的文章,维基:面向对象的设计原则