谈谈“模式思维”

现在各种框架越来越多;模式使用机会性似乎减少了,那么是不是意味着我们就不必掌握模式了呢?其实,学习模式实际为了培养模式思维,模式思维有助于了解和使用框架。

例如如何我们在使用表现层哪个框架,都是MVC模式实现,那么进行编程步骤时,我们脑海里就浮现一个步骤V/C/M以及C和V的转发关系,进而感觉struts-config.xml配置就不是多余或复杂,而是必须的。

现在有人觉得好像Java世界框架特别多,异常复杂,其实这可能是他从封闭世界走向开放自由世界产生的错觉,当你具备模式思维时,实际你就具备了挑选各种各样框架的能力,打个比喻:以选择轿车为例子,过去,只有一种“红旗”轿车供选择,你就只有接受这个轿车;但是现在轿车多了,选择多了,你就必须了解轿车的通用概念,进而你就可以在各种轿车之间选择和衡量,了解轿车的通用概念这个过程就如同我们学习模式,具备通用编程的模式思维,有了模式思维,就会发现有这么多选择产品,不再嫌复杂,而是变得兴奋了;所以,没有复杂的东西,只有是否原意学习的头脑;PC电脑对于一些人很复杂,可是对于我们会复杂吗?不会,因为我们已经掌握通用电脑的模型、模式。

所以,有人觉得Java软件很多配置复杂,甚至产生配置恐惧症,那是因为他没有模式思维,在模式思维指导下的编程工作,就象在写一篇生动的小说一样,你脑海展现的生动模式实现步骤,而无论代码或配置都是实现你模式思维的文字工具,模式思维考虑到哪里,就想起什么配置,配置对具备模式思维的你来说是很自然的表达。

在模式思维下的Java编程,编码阶段code completion可能花费2/3时间,但是调试测试时间只需要1/3甚至不到,大多数情况下是一步到位的调试成功;这比以前1/3编程时间,2/3调试时间要高效多,关键是:你无论花费多少时间在调试上,实际上是在做一个修修补补的工作,是在做维修工,头疼医头,永远是机修工,无法成为设计师。

下面从模式思维角度谈谈几个认识误区,仅仅参考讨论:

游戏软件比企业软件复杂?
为什么说企业软件时复杂的?因为企业软件是为应付需求而变,与游戏软件等软件相比,虽然一个游戏软件在代码数量级别上比企业软件复杂,但是游戏软件不必考虑跟随游戏用户需求变化,是游戏用户服务游戏设计规则;但是企业软件和其用户则相反,企业软件必须服从用户的变化,打个不是很确切的比喻:企业软件则类似市场经济中的市场人员,需要“看客户脸色”行事。而游戏软件则相反,类似以前朝南坐的政府人员;

因此,企业软件在动态概念上是随时间变化而变化,是由生命的,因为计划赶不上变化,所以企业软件制作时总是使用模式为将来变化预留余地,这种面向未来变化考虑方式无疑是最复杂的思维,就象股票变化将这种未来变化的残酷推向极致,我们都想计划未来,但是总是计划不了未来,这就是企业软件的复杂所在。

Class.forName神秘吗?
有人觉得Class.forName很神秘,神秘不在于本身,就是打开其编码研究到二进制也不能达到目的,它的神秘之处是因为应用在一个恰当之处,就象一块普通布没什么,但是如果从后面变出花了,你觉得这块布神奇了,Class.forName神奇之处在于其隐藏了对象创建,也一种是工厂模式实现。

同样,对于Collection,本来就是那几个种类List和Map,但是发现使用起来神奇得很,有人甚至研究过Collection的二进制,这和研究魔术师中一块普通布没有什么区别。Collection用于容器,作为对象集合;以及和单例结合实现缓存等,可以实现多种模式。

仅会算法就做企业软件吗?
在实践中,通常表示一个树形关系通过编码实现,例如1122334455表示是代号为11类别下代号为22类别下的代号为33类别下的....然后,在软件各处通过分析这个类别编码获得树形关系,这种将将具体数据和业务耦合在一起做法是受到抨击的。

那么如果我们要对树形关系的数据进行访问如何实现呢?首先我们将树形关系的访问分为两个部分:树形关系+功能实现。我们已经知晓树形结构的遍历,但是仅仅知道树形结构遍历还是不够的,我们还需要模式来解决树形关系访问这个通用问题,使用Composite模式可以方便客户端对树形结构访问,使得客户端不至于因为树形结构变化而变化不定;而访问者模式则不会总可能新增的新访问功能,导致树形结构中对象代码变化不定。
这两种模式协同发力,可以综合解决树形结构中对象群的访问。
http://www.jdon.com/jive/thread.jsp?forum=91&thread=23857

GoF模式打开的新境界
没有知晓GoF模式之前,我们总是以为编码就是写一些代码,然后运行,复杂吗?如果我们来分析一下GoF模式三个类型,你会发现平时熟视无睹的代码中隐藏如此多考虑方面。

GOF模式三种类型:结构型模式、创建型模式和行为型模式其实函括了OO编码的三个方面:静态类关系、类创建成为运行时对象实例;运行时的对象运行行为,也就是说,我们在编码阶段不但考虑现阶段各个类之间静态解耦关系,而且还要考虑这些代码激活后,运行时的情况。

而以往过程化编程中,编码状况=运行状况,如何先后编码,这些编码运行时就按照这些先后编码顺序执行,两者是统一的,不可能出现运行时可能和编码时预想不一样,更何况需要我们还要在进行类编码时,考虑这些类运行时是如何实现的,有如何对这些类运行时的关系进行解耦和分离呢?所以,我们“天生”就无法理解设计模式,因为我们从来就认为软件就是实现功能,哪里还会考虑到实现同样功能会涉及各种考量了呢?

如果说设计模式是程序员的圣经,那么不掌握设计模式可能就是异教徒,从此教徒和异教徒两者之间就缺乏沟通对话平台,就象鸡对鸭讲话了。

非模式思维的惩罚
面向对象软件体系是和面向过程体系格格不入的,面向对象的各种技术如单元测试 性能缓存等等都是OO体系,如果我们没有具备模式思维来编程,由此而诞生的软件架构必然失败,失败在哪里?通过性能惩罚你。最近碰到一个台湾的钢铁架构,它虽然包含一个简单的MVC框架,但是其Controller实际又是Service,该框架配置将下面几个元素耦合在一起:页面流程;控制类;Dao与VO,这实际是将表现层和持久层直接结合一起,这样的框架迫使程序员没有空间做中间领域模型层和服务层,进而整个体系变成一个两层耦合结构,这和传统的C/S没有区别,在Java中使用传统概念编程:如面向过程、面向数据表以及两层耦合导致结果是性能缓慢,很多大型项目就是这样最后是毁在性能上,服务器需要经常启动,一旦并发用户就很慢,服务器经常死机。

有人可能奇怪:非模式思维属于设计问题,怎么会对性能影响,这是将设计和性能对立起来,性能也是一种设计,池模式以及缓存也是属于模式啊,但是缓存的高效率应用是建立良好的对象设计基础上,或者说是良好的领域建模上,否则就是使用缓存,也会导致粒度或动态机制不准确,无法发挥缓存效率,甚至无法使用缓存。

http://www.jdon.com/artichect/state.htm

为什么说“我们“天生”就无法理解设计模式,因为我们从来就认为软件就是实现功能,哪里还会考虑到实现同样功能会涉及各种考量了呢?”

我这里天生的意思指,我们接受的软件教学,无论是大学还是各种软件学校培训都没有对程序员进行编码各种考量思维拓展培训,这方面知识是空白,所以看到设计模式如同看天书。

下面以最近讨论的decorator模式和Proxy模式说明这种思维拓展的重要,这里表面上是在比较两种模式,其实是在比较为实现同一个功能而出现两种不同的考量。

场景是:我们需要为一个类的方法增加一个新的功能,而且这个功能和原来类的方法中功能不属于同一个方面,因此,我们不能将这两种功能混在一起,所以不能采取修改原来类的方法代码的方式增加新功能,所以增加一个新的类,用新类实现新功能。

这时就存在考量,这个类是做成Proxy类?还是做成Decorator类?这两种不同类的选择因为对未来变化方向有不同的考量。

http://www.jdon.com/jive/thread.jsp?forum=91&thread=26673

拿买菜做菜打个比方:

初用oo技术,像没做过菜的主进了菜场,只知道自己想吃什么,结果可能只买了主菜,而忘记了配料,做起菜来也可想而知了;

模式像是菜谱,心中有谱的话,买菜做菜有板有眼;

而框架就像是熟食档的各类熟食,或者是凉菜,买回去拼个盘,蘸点料,就开吃了

模式与框架两厢比较,当然是框架来得现成了。凡人都喜自来食的。

非常情趣的比喻。技术也能成为一种兴趣,就象我们自己做菜一样,完全可以成为生活的一部分。

在J道讨论技术就是一种生活情趣的体现,这些都是金钱名利换不来的,无论相见恨晚、还是互相攻击,都是对技术的一种真诚执著,都是可爱的,Jdon记录着每个人曾经思考过的轨迹。

是啊,我现在才开始渐渐感到“模式”的招唤,这里面有前人的很多思想能激发自己的感悟。框架固然方便,但只会用现成的而不理解其中很多思想,也许有天也就只能做蓝领了。

小弟觉得设计模式只是给你提供一种很好的设计思想,好比是武术套路。是前人经过大量的项目中总结出的好的,优雅的设计方法。现在大凡软件公司面试,或者学校的考试(当然能够加模式的学校,在国内应该还算不差了)都喜欢去考一种或者几种的设计模式,很多初学者也会觉得掌握了几个模式套路很厉害。其实我认为这是一种错误的想法,就好比武术套路只能用于竞技武术比赛,而街头斗殴,还是要讲眼明手快,手脚并用。其实我认为我们学习模式,使应该掌握他的思维,为什么这样设计,以及采用了模式后能够带来的好处。水平高的程序员在设计程序时,不是为了模式而模式,而是从实际角度出发将模式应用于无形之中,以此达到程序结构的合理的平衡(包括可重用性,性能,编码的复杂度等等)。所以说小弟认为学习设计模式是一个掌握的设计能力的快速途径,但是我们更加应该深入其思想,思维方式,而不是留于表面形式,这样才能体现模式思维的真正魅力。(水平有限,只是个人想法)

>所以说小弟认为学习设计模式是一个掌握的设计能力的快速途径,但是我们更加应该深入其思想,思维方式,而不是留于表面形式,这样才能体现模式思维的真正魅力

严重同意,模式思维其实类似管理思维一样,做管理者必须有管理思维,因为管理者手下很多人,需要协调他们之间关系;而程序员是Class的管理者,当软件中几个class时,无需管理;就象企业初创,只有几竿枪,管理并不重要;但是当软件中有50个左右类时,这时就需要协调它们之间关系,分清主次轻重,搞好配合。

这时也象这几天热门的世界杯足球赛,一个球队有几个主力,有几个是辅助配合,如何处理好主力队员和辅助队员关系,这些都是管理者教练的事情,球员就是class对象,程序员就是教练,你的那些Class是主力,哪些是辅助,都要协调好,协调宗旨就是松耦合。

比如以Ioc模式/依赖注射模式来举例,主力主要职责是进球(业务功能),但是这个功能完成需要其他辅助队员配合,甚至依赖于一些辅助队员,但是在比赛现场时,不可能由主力队员主动安排辅助队员给自己送好球,如果这样,主力队员成了教练了(多个职责),实际上,辅助队员应该如何主动配合主力队员,甚至将一个好球主动送给主力,协助主力进球。这种被调用者(辅助)主动配合调用者(主力)的现象实质是Ioc模式的本质,也称为主动将依赖注射。

模式思维不是教条、不是抽象,它都是来源于我们现实生活中司空见惯的逻辑和案例,关键在于你是否仔细思考了没有?所以单单死记硬背模式,无法领会其本质,也是不行的。

以前我讲比喻不太适合说明模式,其实比喻案例是否到位也体现我们是否对模式理解到位。

个人理解模式思维的难点是要知道在什么样的情景下使用什么样的模式或者模式组合。做好这一步,首先要确实理解所需的情景;然后还要准确的理解各个模式的作用,之后才是匹配工作。我们在日常工作的时候,经常是还没有完全理解所需的情景时,就开始coding了;或者是还没有理解好所用模式的作用后,就生拉硬套的使用了。

搞不明白,banq干嘛整天把缓存,池这些跟oo,3层结构这些绑到一起
不管是面向过程还是C/S结构,都可以使用缓存跟池

觉得讲的太好了
中国软件要强起来没有模式这些东西,难呀
印度为什么这么强也就是这个做得好吗
有自己的模式
banq大哥强
小弟向你看齐

越来越发现其实编程就是那么几个基本的东西~~

软件工程中的软件生命周期,
算法,数据结构,
对象,数据库原理
设计模式

掌握好了这些东西,无论是出生名门的.net,异或是纷繁冗杂的JAVA,还是别的语

言,都可以运用自如,举一反三。

模式思维最大的好处:宏观上把握整个框架的流程走向,对于业务逻辑可预知的扩展和变更留下接口。
难点在于如何预知,如何从众多模式中选择你所合适的,以及在什么时机去使用。
个人理解,还请banq大哥指点。

07年上半年的软件设计师考试,最后那个java题目就考的是策略模式,
不过考得太过肤浅,即使不怎么明白策略模式思想也可以很自然的写出来,小弟就是一个例子,只要明白一些接口回掉就够了,看来传统化的教育对模式还是不是十分重视,只当做一个新兴事物来对待而已。。

以后我要多多关注这个网站了。谈论的话题的确很深入。

大哥写得非常好,我做开发五年乐,理解还是不深入,还是要加油啊.