《JAVA模式》学习心得与体会——之软件设计原则

前言:

近日学习《JAVA与模式》,初看一两遍,简得其义,揣摩其意,深感不得其中精髓,更谈不是灵活应用于实践之中,欲求于网络同行之读书笔记,其意大都是书中摘录,亦无所获;故而私下记录心得体会,一来以众人证明并予指正以便提高,二来以便其他初学者共同学习提高理解之用。

模式概义

多年来,同行非常注重软件设计的:可维护性,可复用性,可扩展性和灵活性,并以此为设计目标;而书中记录下的几大设计原则,为这个宏伟的目标铺平了道路;个人认为这些设计原则对于设计而言,不同的人有不同的理解,就会对设计本身的设计目标造成不同的影响;对后面学习模式的理解也就不一样,深度与广度也不一样。韩非子讲:“国无常强,无常弱。奉法强,则国强;奉法弱,则国弱”;可见对这原则——“法”是多么地重要;而且认识、理解、普及“法”,使之成为“法制社会”;

想当年秦国之所以要变,是因为当时统治者都认识到了自己国家的现状;而现在大家的设计目标正是因为软件设计所面的这些问题,这些问题困扰得我们好痛苦。这些痛苦只有做过设计的人才有真正地难忘的回忆,让人痛不欲生;这些记忆在《JAVA与模式》P.35.中摘录了下来:“过于僵硬,过于脆弱,复用率低,黏度过高”。面对这些问题、困难,我们得思考、总结啊,因此一个好的设计应该很好的体现了:“可维护性,可复用性,可扩展性与灵活性”;为此这些大师们为了这个目标提出了——法,我们这些软件设计公民“依法行事”就可以畅行无阻了。

大家都知道,一个软件是为了解决现实生活中的一些问题,操作系统是为了管理计算机硬件的低层软件而设计,应用系统是为了解决生活中应用问题而设计;不管是面对物还是人,所面对的对象都是一个问题领域;设计是围扰这问题领土完整域来开展的,所以客户的任何要求都是合理的,因为他们是问题域的来源

记得以前在网上看过一段,大意为:“一位好农民,对于地里的庄稼,那怕是最差的那颗,他都会用尽合力让它生长,使之收获;一位好父亲,就算是最不成才的那个子女,他都会尽最大的努力把他教育成才;一位好的教师,班里最差的那个学生,他都会尽最大的努力把他教好;一个好的程序员,客户的任何要求他都会把它们做好”,我想这就是我们为人尽职尽责的职业精神,最基本的职业道德!问题领域的思考对象,问题领域中的

模式的核心——道

阐述我所谓的:“道”,先让我们来认识我说的:“问题领域”:

我把我所谓的的问题领域分成两部份,“静态域”和“动态域”;我们从小到大学习了这么多知识,对一类的事实都有一些共同的看法,或都称它们为知识,我叫它静态域;随着时间的推移,这些事物会发生变化,比如人会老去,但他还是那个人;这类变化的问题我称之动态域;当然这两间都有联系,也存在着转化,如我用太极图(图A)表示:

1.静态域与动态域的表示方法:

首先树型数据与继承等级结构在语义是是想等的;而合成模式与装饰模式也可以生成的链式对象结构,这与线型数据结构也是雷同的。

.静态域:继承等级结构一但确定下来,改变起来就很困难,想重构代码就要花很大的精力(图B),用它来描述静态域再好不过了(因为运行继承的代码比运行动态联结的代码快,而且易于管理);

.动态域:a.图D中有线型数据结构(合成模式和装饰模式<E>可以将它们将对象生成线形结构),用它来描述动态域。

b.图C是桥梁模式,这个模式之所以妙就是利用对象引(关联)把抽象化角色与实现化角色脱耦了;所以接口成了关联、脱耦的重要工具了。(注意:1:接口只是用来代表一个角色,多个角色是对接口的污染——接口隔离原则;2:理会这个模式对于理会策略、状态命令、观察者、建造模式很有意义)

接口的本质:它本身用来表示一个角色,而角色可以代表动态域的一种可变性,它用来参与与静态域的关联,从而形成动态引用。(使用接口与合成聚合模式的好久详情请见《java与模式》一书)

2.细化问题:

解决这个问题领域论的模型最终是要用代码来实现的,既然如此,我们将这些代码分成许多小块,这些小块比函数小,又具有一定的语义,这些小块用集合中的元素表示,称它为元素代码

作用与效果:如果用继承等级结构(树型数据结构)和合成模式与装饰模式(线型数据结构)来组织元素代码,而且元素代码划分得非常合理,我们可以将代码复用的目的达到最大限度。

步骤:元素代码之间不组合形成不同行为,不同的行为又组合成不同的类;而这些类之间又有相同的元素代码,从而组合成了继承等级结构与链式结构;这个过程要用分类思想来作指导,结果要使类从分类学上有意义。

A.用继承的工具来描述这些组合,共同的元素代码尽向上移,数据尽量向下移;这样做的好外非常明显,一来这种组合已经定义好了,二来在新的需求下,找准自己想要的结点来复用已有的代码,使之成为该结点下的叶子结点;缺点就是这个组合早已经成为定局,想从新组合就非常困难。

Ba.用合成模式、装饰模式动态生成对象链,让它们动态联结代码,这样的确非常灵活,但这样的小类太多了,实在难于管理。好处就在于解决了继承等级的缺点;这好比一个男人在外面有了太多的女人,把关系搞得过于复杂,此人虽然艳福不浅,但也有隐痛啊!比如金庸先生的《天龙八部》里的段正淳就是一例。

b.静态域可以用一个接口的形式来管理动态生成的对象链,它可以用来代表一个角色,从而封装一种可变性;是支持角色的一种机制;也可以这样理解:静态域是消费者,实体角色是产品,接口是说明书。

3.两种域之间的关系:

静态域与动态域的转化:问题领域中不确定的变化的现像,在经过长期实践是可以转化静态域的知识,而静态的知识随着时间的变化也是会过时的。

例如:几亿年前,猴类随着时间、环境的变化,最终进化成为人类;那你有可能会问,如果人不思劳动,像动物那样天天只知道吃喝睡玩乐,会退化为之前的猴吗?这个问题我想没有人知道,应该由时间来证明,呵呵!不过这就是归纳总结知识,然后再将这些知识运用与生活,然后再归纳与总结,如此反复,才得以发展;这就像钱一样,你存到银行对你来说并没有发挥它的作用,如果你把它用来投资,使它运作起来,才得以实现它的价值——属于你的摇钱树,你想要一棵吗?

这种关系的转化还有另一种表述——进化,演化,用这个词来形容,说明了在软件系统生命周期里,它需要这种变化来适应现实情况;如果设计考虑到这种进化,那么代码的灵活性将非常高。(注意我说这种进化并不是指封装一种可变因素,那怕是继承等级结构)

以上我用两种工具:抽象类的继承等级结构与链式对象结构,和一个思维方法:组合元素代码块,以及静态域和动态域之间的关系来阐述了图A。

在此声明我不是故作高深玄妙,我要把这些模式模式简单化,简单到不能再简单的地步,直指问题的核心,这个核心问题我称它为:“道”。

4.对道的理解

不管是建立的模型是解决的那些问题,所对的对象都是现实世界的事物;而这些事物都会随着时间的推移发生着变化,而这个物质世界所有的事物只有变化着、运动着,才得以有存在的意义,这种运动与变化我用老子的一个“道”字来形容;而我们又只有对我们所研究的对象有全局的认识并把握,之后才能得道,才能设计软件模型,才能理解模式,运用模式;道就在问题领域的运动之中,就在脑海与荧屏之间,代码与文档之间,文档中有模式,模式中存在道,道存在于我们吃饭的时候,在我们上班的路上,在你跟美女之间……。

软件设计中的设计原则——“法制”

此“法制”是为了达到设计目标:“可维护性,可复用性,可扩展性和灵活性”而制定的;理解这些设计原则需要与各种模式及多个项目的参考的基础之上,才能体会其中的意思。

1. 这些原则之间的关系

a.开闭原则讲的是一个软件实体应当对扩展开放,对修改关闭。开闭是目标,依赖倒转原则是步骤;依赖倒置原则是手段,机制

在继承等级结构中里,讲的是共用代码要向上移,数据向下移;目的并不只是为了代码复用,它还可以引用父类的地方,子类也可以出现;因此我们用继承等级结构来组织代码,并遵循Coad条件(java与模式P.64.);在我们编码时讲究这些,也就达到了里氏代换原则的要求。这是不是实现开闭原则的步骤呢!

当我们还是初学者的时候,都喜欢用已有的类作为父类,从而来感受OO的好处;现在才明白这种复用的工具是在OOD的时候就已经决定了的,所以在一般情况下使用组合聚合关系来达到复用的目的是有一定道理的。这样做不但没有滥用继承(到底滥用了没有也许只有以后才能发现,当发现时来重构就要花时间了),还从一定层度上支持了里氏代换原则。

如果我在编码的时候尽量引用高层次的抽象类、接口,这样就做到了细节依赖于抽象,这就是针对接口、抽象,不针对实现编程,从而也就达到了依赖倒置原则,此过程就是做到了开闭原则的机制和手段

如此我们的代码在可维护性,可复用性,可扩展性和灵活性方面是不是就大了呢!

b.首先我们得认识接口本身是用来作类型声明的,抽象是用来作继承用的;而接口是用来代码一个角色,类是用来代表一个分类、一个事物;接口隔离原则为什么不要接口原则就是这么一个道理,因为接口是用来表示一个角色而不是二个或者多个。

类可以继承一个接口,因此类就成了这个接口的实例、演员;类可以引用一个接口,这个类就可以拥有很多角色的实例、演员,因此这个类从用户角度来讲同一意义的事情、职位可以由不同的事物、人来充当,从开发人员的角度来讲就是抽象化角色与实现化角色脱耦。

合成聚合原则是继承复用工具的一种替代方案,并充分运用了接口的好处;在模式中的装饰模式就把这种意图体现得淋漓尽致。另外桥梁模式也正是引用了这一原则把实现化角色与抽象化角色分离,使得其它模式(如:状态模式、策略模式、观察者模式和命令模式)都利用了这一特长。{通过深刻理解了这些原则之后,也许我们自己也可以创造另外一个实用的模式出来}

c.最近听一朋友说:“处事的啊,把关系搞得越简单就越好”;圣人老子也这样讲,使民无知,不相往来;初一看,跟大多数人的观点一致,认为在当时的时代,各国为了私欲年年混战,民不聊生,各国争用贤才;所以很多评论说在老子的那个时代,这种观念来治国很适合当时情况,现在看来,我不能赞成这样的观点了,因为这样理解只停留在字面意义上;假如我们把我们身边的朋友,邻居的关系处理成:交往没有利益共享,交往没有冲突原因,虽不是血亲那样亲密,但彼此相互尊重,如此人生也会少一些不必要的、无意义的矛盾。

我想迪为特法则的用意就在于此,我们现在来看看不遵守这个法则会怎么样,我见过好多系统每一个类里有几十个函数,在这样一个关系复杂的系统里分的类也不多,对象之间的关系相当复杂,如果想升级,我相信作者本人也要花费非常大的力气。

再回头看看图F和图G,图F是为了a.而作说明,图G是为了说明b.;观点a(F)说明了继承等级结构生成与作用及三原则的关系;观点b(G)也说明了整体与部分的运用以及与开闭原则的关系;如果在遵守两图包含的5个原则再加上迪为特法则,那么这个系统的可维护性,可复用性,可扩展性和灵活性方面,将大有增加。

因此我们作为初学者,不但要养成好习的习惯,还要在开发的时候一定要对问题要有一个全局的认识,把属于角色(动态问题领域)的部分提取出来,用接口这个工具把共同性抽象出来;对于属于静态问题域的方面,用继承等级结构来表达;这两方面都在语义上有一定的意义,而且尽量划分成小类;在代码实现的时候,尽量引用高层次的抽象类或者是接口。最后我们在随时总结知识,并把它们归纳成自己的语言,形成自己的知识,最终有一套属于自己的理论——真理,然后我们再推广现实生活并加以验证,如果反复。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值