从设计原则谈软件开发(四)

        上一次说LSP(李氏代换原则),写的有些着急。很多东西都没有写出来,这次首先来补充一下。

        其实就是补充一个例子。这是《JAVA与模式》中的一个例子,是说正方形是否可以继承自矩形。我相信基本任何一个读过小学的人几乎都不会不假思索地(包括我)说,正方形就是特殊的矩形,当然可以继承了。但是却恰恰相反。理由如下:在矩形中应该有这样一个方法,是改变矩形的长和宽,这个时候假设有一个方法是void Change(double 长,double 宽),但是这个方法换到正方形中却应该是void Change(double 边),也就是说此时长方形作为正方形的父类却不能替换掉子类,于是也就是说不符合LSP。其实我认为这个理由有些过于牵强,如果这样说的话,我也是同样把正方形中的方便变为void Change(double 边,double 边)也未尝不可。但是通过这个例子,我们应该认识到在LSP在不同的情况下,会产生不同的结果。还是上次举到的企鹅是不是鸟的问题。如果鸟这个类中有着Fly()的方法,那么企鹅就不是鸟,但是如果鸟这个类我现在并不需要鸟的Fly()的行为,而只是需要他Eat()之类的方法,那么让企鹅来继承鸟类也未尝不可。

         总之,设计模式的目的本来就是为了可扩展,可维护。所以封装变化封装的其实就是变化点。在不同的系统中,变化点一定是不同的,打个比方,在学生管理系统中,有一个学校的学号位数是4位,随着这个学校的壮大,四位肯定是不够的,那么这个学号的位数很可能成为一个变化点。但是如果一个学校的学号是24位,那么我想我们就没有必要把这个做为一个变化点来处理了。

         接下来,来说一下DIP(依赖倒转原则).DIP的内容是应该依赖于接口,而不是实现编程。这个是设计模式中一个最典型的现象,几乎每个设计模式都会典型地满足这个原则。其中,我们来看一下最典型的Facade(外观模式)。

         外观模式的意图是为一个子系统或者子模块提供一个统一的接口,然后让高层模块来调用这个接口,而不需要知道子系统中实现的细节。

         结构图如下:(引用自http://terrylee.cnblogs.com/archive/2006/03/17/352349.html):

        

        园子里有很多设计模式的文章,如果朋友们有哪里不大清楚可以去看一下那些文章,在这里,我不具体讲这个模式的内容。我来主要谈下他的应用。

        您如果有过工作带实习生的经历,一定有过这样的经历。很多实习生没有经验,编程水品又差。当你分配给他一个模块的时候,他就做的乱七八糟。写了一大堆类,一大堆方法,没有注释,也没有什么命名规范。然后给你。这个时候,你就得需要一点点地分析他的类,分析他的方法。结果最后下来,比你自己写一个模块还要耽误时间。于是,你可以采用这样的方法。给他规定几个接口,然后让他去实现这些接口,然后把它写的那些类通通封装到一个程序集中,这样,你就不需要知道他的内部实现细节,只需要引用他的dll,然后调用它的对外接口就可以了。

        其实,这个模式在很多地方都有应用,您如果有过软件开发经验,最熟悉的莫过于三层架构或者是N层架构,每层与每层之间其实不都是通过一个接口来完成交互的么!这其实就是外观模式的典型应用。

        总结一下我对外观模式的理解:

        1.为子模块或子系统提供一个统一接口,方便其他模块调用。

        2.增加了子模块的系统独立性,方便其他类的调用。如上图中的ClientA,ClientB,ClientC。

        3.易修改,我需要的只是你的对外接口,你的接口不改,我就不需要管你内部的实现逻辑。每个人维护自己的模块,升级时互不干涉。

        回到主题,DIP,还是说三层架构的例子。DIP也有这样一种说法,是高层依赖于底层,而底层不能反过来依赖高层模块。无论是哪种说法,我们都来解释一下。还是说那个经典的三层架构。数据访问层,无非是整个系统的最底层模块,这个模块提供了一系列接口,供他的上一层业务逻辑层调用,而业务逻辑层只需要知道数据访问层的对外接口,数据访问层也根本不知道业务逻辑层的存在。业务逻辑层与用户界面层也是一样的关系。这其实就是模块的系统独立性。

        今天把这个系列写完,最后一个设计原则,ISP(接口独立原则),这个原则的目的就是一点,如果用户不需要一个功能,那么就不要强迫用户实现这个功能。

        这个其实我认为和SRP的方法是差不多的,就是分割。在SRP中,我们把一个类分离,让一个类只有一个能够引起他变化的原因,而在ISP中,我们是把一个接口分离,使他不会被一个用户强迫实现,这也就是我之前说过的分离接口的艺术。接口里的方法太多,这个接口中注定要有方法被强迫实现;接口中方法太少,就会产生很多碎接口,影响程序的运行效率。而接口其实本质上就是一个类罢了,因此我实在不觉得ISP和SRP有着什么样的区别。所以,在这里就不太重复一些废话了。

        这个系列结束了,我做个总结吧。首先,还是先声明,我也只是个学生,没有过大的项目经验,所以,很多也只是自己的感性之谈,各位如果有什么看法,希望可以多多指教。

        其实,第一次看设计模式时,觉得很深奥,23种模式实在背不下来,然后就开始一遍遍地看,在做东西的时候强迫自己去应用。当看到第五遍第六遍的时候,开始发现几乎设计模式其实都是差不多的,于是开始反过来看设计原则。然后发现,其实不同的模式,只是应用设计模式,针对各种变化点,采用不同的封装模式,封装不同的变化点罢了。然后开始反复的看设计原则,一点点地理解设计原则,然后再开始看设计模式,就觉得容易了很多。在软件中也可以比较容易地应用设计模式了。

        这个系列结束了,谢谢大家一直的关注。无论是无意点进的,还是点击观看的,呵呵。看到浏览量的增长就是我学习,和写下去的最大的动力。就像我主页上写的,我学习软件的目的就是希望自己能够为中国IT贡献自己的一份微薄之力。我会更加努力,希望可以像那些MVP一样,提高自己的水平,为中国的IT真的贡献自己的一份力量。

    

        系列参考资料:

        TerryLee:http://www.cnblogs.com/Terrylee/archive/2006/07/17/334911.html

        《大话设计模式》

        《你所必须知道的.net》

        《Head First 设计模式》

posted @ 2008-09-16 09:40  飞林沙  阅读(1904)  评论(4编辑  收藏  举报