34岁!100天!学会Java编程(Day49-Day52)—OOP设计模式

新书发布会

下午的昊海楼9层阁楼,阳光从分别从西侧落入,再从东侧大厦的玻璃幕墙反射回来,将阁楼填满了阳光。在这样的阳光下目睹一本新书的发布,有一种迷幻的味道。

(一)为什么要学设计模式?

如果说数学是思维的体操,那设计模式,就是面向对象编程思维的体操。

这里的设计模式,特指四人帮(GOF)于1995年出版的“Design Patterns-Elements of Reusable Object-Oriented Software”中所描述的面向对象的设计模式。当时面向过程的结构化编程正如日中天,面向对象方兴未艾,人们或许知道面向对象的三大特性:封装、继承、多态。但是在实践应用中,与面向过程相比就不免显得结构复杂,不够直观。此时,四人帮将程序员在面向对象编程过程中的最佳实践提炼成了23个设计模式,逐渐开始流行,然后成了程序员们的黑话,而面向对象方法对于程序维护、需求更改、功能扩展的良好适应性也逐渐影响整个行业。

说到这里,上面的问题就有了答案,学习了OO设计模式,并且在编程中养成了模式思维,才算是真正领悟了面向对象编程的妙用。

结合面向对象的六大原则,OO设计模式描述了类的抽象、剥离与组合,类集的典型结构与行为。但是模式不能孤立存在,对于每一个的功能类,向下都需要底层的数据结构与算法作为支撑来实现。而模式与模式的组合,向上则构成了软件的架构模式。

(二)OOP设计模式

GOF总结了23种设计模式,虽然现在的OO设计模式远不止这23种,但一开始的学习仍应从这里开始。具体的参考书目见文末,下面上图:


OOP设计模式

图中每一种设计模式都值得细读,不过篇幅所限下面简要介绍OOTV大赛五强选手。

(1)工厂方法模式
先聊一聊工厂方法三姐妹,她们包括:简单工厂,工厂方法,抽象工厂。他们都是使用户在不需要知道具体产品细节的前提下,保质保量的完成产品实例化的方法。比较而言,简单工厂,在工厂内部设置若干条件分支,使客户按需订制,优点是简单无需产生大量的类,缺点是不符合开闭原则,一旦有变更,就需要修改方法内部条件分支。工厂方法,将产品实例化延迟到她的子类,应对变更时只需要对工厂子类进行扩展。如果说工厂方法只是对产品进行简单的加工生产,抽象工厂,则可以满足更加复杂的装配生产。下面回到工厂方法。
情景:客户需要从若干产品中得到自己需要的产品,又不想知道产品的构造细节时。
问题:客户直接调用产品的构造器会使两者形成强耦合,不利于应对变更。
解决方案:使用工厂方法进行隔离。使得变更产生时,无需修改高层用户类。
UML图:见书,略
实际应用:商户需要订购1000台iphone,500台ipad,不需要自己找来图纸建设工厂,只需要向工厂发送订单即可。这样不论iphone如何升级换代,商户与工厂的接口不会改变,工厂包装了产品细节。

(2)适配器模式
情景:当开发软件需要使用第三方插件,但是接口与现有体系不同时;当软件升级换代重构后,必须使用原有组件,但是接口与新体系不同时。当需要调用的第三方软件(如DB)预计可能发生变化时。
问题:两个接口不同的组件,难以直接调用,或者预计会发生变更。
解决方案:使用适配器进行过渡。
UML图:见书,略
实际应用:你的安卓手机在路上快没电了,你忘了带充电器,而此时你朋友带着苹果充电器。嗯,这时你只需要一个适配器。

(3)外观模式
情景:软件开发中需要调用一个有多个具体功能模块的子系统时。
问题:直接地调用子系统中多个功能模块,会产生强耦合。
解决方案:给子系统添加一个facade接口,所有对子系统的调用都通过他来实现。
UML图:见书,略
实际应用:好的模式:去银行不管办什么业务都只需要找到一个柜员。反模式:去医院看病,你需要在挂号,分诊,看病,缴费,检查,取药每一个环节面对不同的人。

(4)观察者模式
情景:当一个事件发生,需要通知若干个对象做出相应反应时。
问题:事件源可能并不具备通知功能。
解决方案:设置一个观察者,当事件源发生时,通知注册会员(若干注册的监听者)做出回应。
UML图:见书,略
实际应用:一伙賊做坏事时,总会需要一个人在外围放哨。

(5)策略模式
情景:当一个类中部分功能稳定,部分功能有几种不同变化时。
问题:变化会给类的使用带来灾难性后果。
解决方案:将变化从类中剥离出来,单独封装,并提供接口调用。
UML图:见书,略
实际应用:哄老婆三板斧:甜言蜜语,送礼物,拿钱砸。嗯,还可以扩展。

(三)复合模式

日常软件开发可能需要用到若干种设计模式组合使用的情况,这在《Head First设计模式》中进行过案例探讨。

几种模式的使用若仅适用于当前软件,则仅能称之为普通的模式组合。若有一种组合能够抽象出来具有普适性,可应用于多种场合,则称之为复合模式。而MVC模式也被该书称之为复合模式之王。当然,先有MVC模式,还是先有GoF模式,我没时间考证,姑且认为MVC模式就是从GoF模式进化而来。

MVC模式中的单体模式:
(1)Controller:策略模式。当客户端发送一个请求,可以认为用户调用了Controller的一种策略,每次调用产生一个行为,成为事件源。
(2)Model:观察者模式。在这里,Model中的不同模块被定义为不同的观察者,用于观察Controller中特定策略产生的事件源,并通知给注册的监听者View。
(3)View:组合模式。被通知的View,将所需的子节点与叶节点进行组合,响应给客户端。

CEv5.0框架重构

按照该MVC模式来审视我之前CEv5.0项目的MVC框架,确实并不符合面向接口和封装变化的精神,对其再次重构,则有以上框架图。

说说个人的感觉,理想中的MVC模式适合于桌面软件开发,对于Web应用,对于Servlet/JSP有这么几点不同:
(1)严格符合MVC模式的只有Controller模块,当浏览器发送Request时,可以有get、post、put、head、delete等8种策略(method)可以选择。

(2)View模块。JSP不是面向对象的,所以不能简单套用组合模式,不过Html文件的文档结构,的确是符合子节点和叶节点组成模式的。

(3)Model模块。在观察者模式中,观察者是通过调用监听者的响应方法来通知监听者的。在这里,由于JSP不是对象,不得不做一些调整。可以通过在Servlet中添加Dispatch方法作为Model的回调函数,来通知JSP对浏览器做出响应。

(四)设计模式的实际应用

(1)用模式审视自己的设计
这里本来想写,用模式思维来设计软件,后来觉得不妥,这样容易直奔过度使用模式而去。

关于过度使用设计模式是另一个话题,这里我觉得比较正确使用模式的姿势是,遵照OO设计六大原则去设计自己的程序框架,然后找出其中可能发生变更的地方,再用模式思维去审视自己的设计,并做出改进,然后再去实现细节。

当然,模式就像一套剑谱,真正的高手是无招胜有招,胜人者剑意而非剑形。我等小菜还是心怀理想,然后老老实实照着剑谱去练吧。

(2)过度使用设计模式的问题
学习模式也有一个坏处。学会了模式,就像有了一把锤子,看什么都像钉子,想去敲一敲。后果是什么?就是造成程序要做的事本来很简单,结果实现方式却过度复杂。

不过书中的建议是,初学者过度使用也无妨,哪怕用错了地方也无妨,这样反而可以使用中快速精进。等到真正熟悉了大部分模式的用法后,再去判断何时何地当用何种模式。

(3)反模式的用处
什么是反模式?通俗一点讲,就是关于模式使用的错题集,尤其是当用模式而不用,当变化来临时,造成十分被动的典型情况。

(4)更多的模式
除了1995年出现的GoF23种模式,二十多年间,不少工程师还把自己在工作中反复遇到的问题提炼成了模式,并且在网上与人们开源共享。主要包括两类:一是面向对象编程OOP设计模式的进一步扩展模式;二是用在其他地方的譬如架构模式、应用模式、业务流程模式、组织模式、用户界面设计模式、网页设计模式、领域特定模式等,可以作为进一步学习升级的方向。knowmore1knowmore2

参考书目
《设计模式:可复用面向对象软件的基础》
《大话设计模式》
《Head First设计模式》

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,847评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,208评论 1 292
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,587评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,942评论 0 205
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,332评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,587评论 1 218
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,853评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,568评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,273评论 1 242
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,542评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,033评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,373评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,031评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,073评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,830评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,628评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,537评论 2 269

推荐阅读更多精彩内容