看了大话设计模式,想自己总结一下,以加深印象。本次来总结设计模式中的设计原则。(以下大部分来自大话设计模式)
一:单一职责原则
它的准确解释是:就一个类而言,应该仅有一个引起它变化的原因。
通俗的说,就是一个类不应该有太多的职责,不然的话,当需求发生改变时,你要改动的地方可能非常多且复杂,设计会遭到意想不到的破坏。比如在数据库设计中,如果在一个类中,既要从数据库中取数据,又要对这些数据进行归纳整理,那么这个类就不是好的设计,当需求改变时,整个类可能都要修改。应该把它们放在不同的类中,一个类只负责一个功能,只取数据或者只整理数据,那么当需求改变时,只用修改整理数据的那个类就好了。
如果一个类承担的职责过多,就等于把这些职责耦合在一起,一个职责的变化可能会削弱或者抑制这个类完成其他职责的能力。这种耦合会导致脆弱的设计,当变化发生时,设计会遭受到意想不到的破坏。
二:开放-封闭原则
它是说软件实体(类、模块、函数等等)应该可以扩展,但是不可修改。
也就是说,软件实体,最好能够通过继承同一个父类等来进行功能扩展,最好不要在已经写好的类里面进行修改。
即面对需求,对程序的改动是通过增加新代码进行的,而不是更改现有的代码。
绝对的修改关闭是不可能的。无论模块是多么的‘封闭’,都会存在一些无法对之封闭 的变化。既然不可能完全封闭,设计人员必须对于他设计的模块应该对哪种变化封闭做出选择。他必须先猜测出最有可能发生变化的种类,然后 构造抽象来隔离那些变化(通过继承、封装等)。
当然,并不是什么时候应对变化都是容易的,我们希望的是在开发工作展开不久就知道可能发生的变化。查明可能发生的变化所等待的时间越长,要创建正确的抽象就越困难。
开放-封闭原则是面向对象设计的核心所在。遵循这个原则可以带来面向对象技术所声称的巨大好处,也就是可维护、可扩展、可复用、灵活性好。开发人员应该仅对程序中呈现出频繁变化的那些部分作出抽象,然而,对于程序中的每个部分都刻意的进行抽象并不是一个好主意。拒绝不成熟的抽象和抽象本身一样重要。
三:依赖倒转原则
A:高层模块不应该依赖底层模块,两个都应该依赖抽象。
B:抽象不应该依赖细节,细节应该依赖抽象。
什么是高层模块依赖底层模块?举个例子,面向过程开发时,为了使得常用代码可以复用,一般都会把这些代码写成许许多多的函数库,这样在做新项目时,去调用这些底层的函数就可以了。但为什么高层模块不应该依赖底层模块?比如项目大多时候都有访问数据库,所以就把访问数据库的代码写成了函数,每次写新项目时都要调用这些函数。如果不管高层模块还是底层模块,他们都依赖于抽象,具体一点就是接口或抽象类,只要接口是稳定的,那么任何一个地方的更改都不用担心其他的地方受到影响,这就使得无论高层模块还是底层模块都可以很容易的复用。
为什么依赖了抽象的接口或抽象类就不怕更改呢?因为有一个里氏代换原则。
里氏代换原则简单的说就是子类型必须能够替换掉他们的父类型。也就是说,在软件里,把父类都替换成他的子类,程序的行为没有变化。只有当子类可以替换掉父类,软件单位的功能不会受到影响,父类才能真正被复用,而子类也能够在父类的基础上增加新的行为。比如说,在面向过程设计时,有一个鸟类,有一个企鹅类,鸟类可以飞,尽管企鹅在生物学上是一种特殊的鸟类,但他在这里却不能继承鸟类,因为他一旦继承了鸟类,他就继承了父类的方法,具备了飞行的功能,但企鹅是不会飞的,所以不能继承鸟类。
正是由于子类型的可替换性才使得使用父类的模块在无需修改的情况下就可以扩展。
四:迪米特发则
迪米特发则是说,如果两个类不必彼此直接通信,那么这两个类就不应当发生直接的相互作用。如果其中一个类需要调用另一个类的某一个方法 的话,可以通过第三者转发这个调用。
迪米特发则其根本思想是强调了类之间的松耦合,我们在程序设计时,类之间的耦合越弱,越有利于复用,一个处在弱耦合的类被修改,不会对有关系的类造成波及。