声明:下面列出的面向对象程序设计原则并非我个人总结,而是最近学习设计模式的笔记。目前只是列出刚看过的几条,以后学到再继续添加。
1. 单一职责原则(SRP)
单一职责原则,就是,就一个类而言,应该仅有一个引起它变化的原因。
也就是说,一个类应该只实现一个单一的功能。为什么呢?因为,如果一个类承担的职责过多,就等于把这些职责耦合在一起,一个职责的变化可能会削弱或抑制这个类完成其他职责的能力。这种耦合会导致脆弱的设计,当变化发生时,设计会遭到意想不到的破坏。比如我们写一个窗体应用程序,一般都会生成一个Form1这样的类,于是我们就将各种各样的代码,像某种功能的算法啊,数据库访问的SQL语句啊什么的都写到这样的类中,这就意味着,无论任何需求要来,你都需要更改这个窗体类。这其实是很糟糕的,维护麻烦,复用不可能,也缺乏灵活性。
软件设计真正要做的许多内容,就是发现职责,并把这些职责相互分离。如果你能够想到多于一个的动机去改变一个类,那么这个类就具有多于一个的职责,就应该考虑类的职责分离。
2. 开放-封闭原则
开放-封闭原则,是说软件实体(类、模块、函数等)应该可以扩展,但是不可修改。
这个原则其实有两个特征,一个是说“对于扩展是开放的(Open for extension)”,另一个是说“对于更改是封闭的(Closed for modification)”。其实就是所谓的“高内聚,松耦合”。这样,面对需求,对程序的改动是通过增加新代码进行的,而不是更改现有的代码。
开放-封闭原则是面向对象设计的核心所在。遵循这个原则,可以带来面向对象技术所声称的巨大好处,也就是可维护、可扩展、可复用、灵活性好。开发人员应该仅对程序中呈现出频繁变化的那些部分做出抽象。然而,对于应用程序中的每个部分都刻意进行抽象同样不是一个好主意。拒绝不成熟的抽象和抽象本身一样重要。
3. 依赖倒转原则
A. 高层模块不应依赖于低层模块。两者都应依赖抽象。
B. 抽象不应依赖于细节。细节应该依赖于抽象。
为什么叫倒转呢?在面向过程开发时,为了使常用代码可复用,一般都会把它们写出许多函数的程序库。在做新项目时,去调用这些低层的函数就行了。比如我们做项目时大多要访问数据库,我们就把访问数据库的代码写出函数,每次做新项目时就去调用这些函数。这就叫做高层模块依赖低层模块。这样做的问题是,我们要做新项目时,发现高层模块的业务逻辑都是一样的,但客户却希望使用不同的数据库或存储信息方式,这时就出现麻烦了。我们希望能再次利用这些高层模块,但高层模块都是与低层的访问数据库联系在一起的,没办法复用这些高层模块。而如果不管高层模块还是低层模块,它们都依赖于抽象(接口或抽象类),只要接口是稳定的,那么任何一个的更改都不用担心其他受到影响,这就使得高层模块和低层模块都可以很容易的被复用。
里氏代换原则
子类型必须能够替换掉他们的父类型。
里氏代换原则是Barbara Liskov女士在1988年发表的,具体的数学定义比较复杂,白话翻译就是一个父类出现的地方,一个可以用子类去替换掉它,而且不对程序造成任何影响。就是说这软件里面,把父类都替换成它的子类,程序的行为不会发生任何变化。
正是由于子类型能够替换掉他们的父类型,才使得使用父类型的模块在无需修改的情况下就可以扩展,才有可能实现依赖倒转原则,才有可能实现开放-封闭原则。
依赖倒转其实可以说是面向对象设计的标志,用哪种语言编写程序并不重要,如果编写时考虑的都是如何针对抽象编程,而不是针对细节编程,即程序中的所有依赖关系都是终止于抽象类或者接口,那就是面向对象的设计,反之那就是过程化的设计了。
参考阅读: