设计模式学习笔记三:开发原则,开放-封闭原则,依赖倒转原则

一,单一职责原则

  当我们已面向对象思想编写程序,所有的类不能太过复杂,不要吧太多的功能在一个类中实现,比如一个网站页面文件,他的后台类里只能有操作页面显示的功能其他的业务逻辑和规则都不应该写在这个页面中,为什么?“如果一个类承担的职责过多,就等于吧这些职责耦合在一起,一个职责的变化可能会削弱或者抑制这个类完成其他职责的能力。这种耦合会导致脆弱的设计,当变化发生时,设计会遭受到意想不到的破坏”。

  我们经常会说恶性耦合,良性耦合,如果吧原来不是这个类应该承担的职责也写进这个类的代码中,那么这个就是恶性耦合,“软件设计真正要做的工作就是发现职责,并把它们互相分离开来”,一般来说如果某一个类当我们想到多于一个的动机去修改这个类,那么这个类就具有多余一个的职责,这个时候我们就因该考虑分离这个类,当然这个说来容易做起来缺很难,需要经验的累计,当然这个设计思想其实我们平时每天都在接触,那就是页面和业务逻辑的分离,一般页面的展示需要变动是非常平凡的,然而后台业务逻辑的变更则是少的。

 

二,开放-封闭原则

  提倡面向对象的人总是在宣称面向对象设计的好处在于“可维护,可扩展,可复用,灵活性好”,这些好处如何实现呢?开放封闭原则就是达成这些条件的核心要素,开放封闭原则,是说软件实体(类,模块,函数等等)应该可以扩展,但是不能修改,无论模块是多么封闭,都会存在一些无法对之封闭的变化,既然不可能完全封闭,设计人员就必须事先猜测出最有可能发生的变化种类,然后构造抽象来隔离这些变化,这里需要注意的一点是,当开发工作开展后,需要努力的查明可能发生的变化,因为等待的时间越长,我们要创建正确的抽象就越困难。

  如果可以正确的遵循这个原则,可以带来面向对象技术所声称的巨大好处,开发人员应该仅对程序中呈现出频繁变化的那部分作出抽象,然而,对于应用程序中每个部分都可以的进行抽象是错误的,拒绝不成熟的抽象和抽象本身一样重要。

 

三,依赖倒转原则

  依赖倒转原则的原文解释是“抽象不应该依赖细节,细节应该依赖抽象”,理解起来其实就是针对接口编程,不要对实现编程,下面举一个开发过程中普遍会意见的问题来阐述这个观点。

 

  例:一个项目要访问数据库,所以我们把访问数据库的代码写成了一个函数,然后在每次开发新页面或者新功能模块的时候我们都去调用这个访问数据库的函数,在这里我们把访问数据库的函数定义为底层模块,把调用这个函数的各个页面和业务逻辑模块理解为高层模块,这样做乍看之下是没有问题的,但是如果客户需要更改使用的数据库,这下可就尴尬了。

  我们试想一下,高层模块和底层的访问数据库是完全绑定在一起的,没办法复用这些高层模块,这样一个简单的需求变更就有可能造成大量的程序修改,那么依赖倒转原则又怎么解决这个问题呢?

 

  这里要说一个叫做里氏代换的原则,“一个软件实体如果使用的是一个父类的话,那么一定适用于其子类,而且察觉不出父类对象和子类对象的区别,也就是说,在软件里面,把父类替换成它的子类,程序的行为没有变化”,子类必须能够替换掉他们父类,简单来说就是任何一个子类必须包含父类除了私有以为的所有方法功能,这样就可以替换父类并且完全不影响已经在运行的程序模块,这样子类可以替换掉父类,软件单位的功能不受到影响时,父类才能真正被复用,而子类也能够在父类的基础上增加新的行为,我个人觉得这样的继承关系是面对对象的核心,只有有了这样的继承替换,开放-封闭原则才有可能得以实现,正是由于子类的可替换性才使得父类的模块在无需修改的情况下可扩展。

 

  现在回到上面举的这个例子,如果我们在底层模块(数据库访问函数)和高层模块(业务逻辑)的中间放置一个中间件(抽象类or接口),的话面对需求变更时候的情况就完全不同了,我们根本不需要去修改高层模块的中代码,之需要在接口中做适当的修改,并且增加一个数据库访问函数就可以解决这个问题了。

 

  依赖倒转其实可以说是面向对象设计的标志,如果编写的时候考虑的是如何针对抽象编程而不是针对细节编程,那么程序中所有的依赖关系都是终止与抽象类或者接口,那就是面向对象的设计,反之那就是过程化的设计了!

posted @ 2011-12-08 16:37  适渊  阅读(169)  评论(0编辑  收藏  举报