关于GOF的23种设计模式许多人已经耳熟能详,这段时间把程杰的《大话设计模式》过了一遍,略有感悟,和大家共勉。
首先看一下模式的定义:
模式:在某情境下,针对某问题的某种解决方案。
情境:应用某个模式的情况。这应该是不断重复出现的情况。
问题:你想在某情境下达到的目标,但也可以是某情境下的约束。
解决方案:这是我们的目标。一个通用的设计,用来解决约束,达到目标。
个人认为设计模式就是为了处理不断变化的需求,充分利用面向对象的特性——封装、继承、多态和抽象来达到所谓的OCP——对修改封闭,对扩展开放等面向对象设计原则的目的;最初,我以为,只要掌握了不同设计模式的变与不变就掌握了设计模式。如抽象工厂,其变化是:实现系统可能有多角度的分类,每一种分类都有可能变化,比如说手机应用,按品牌分可分为诺基亚、西门子、苹果等;按应用分则可分通讯簿、M游戏、N游戏等,而不变的则是每个具体的品牌的接口和应用,比如说通讯簿就是为了存放联系人的信息。再如:模板方法模式,其不变的是不同场景下要完成某一过程的步骤一样,变化的是,完成某个步骤的细节上可能不一样。后来,当我发现很多模式又极其相似时,我疑惑了:建造者模式的变与不变好像与模板方法模式一样?至今,仍有很多模式间的细微差别不是很了解,一次偶然机会,看了《大话设计模式》的序言后,才发现,原来很多人都会有这么一个过程。
作者说,设计模式有四境界:
1. 没学之前一点都不懂,根本想不到用设计模式——个人认为用“想不到利用面向对象的特性”更确切,而且很多没有学习设计模式,却很有经验的人,在写代码中自然而然地用到了模式而不自知,比如典型的模板方法模式
2. 学了几个模式后,很开心,于是处处想着要用设计模式——现实中我也遇到了这样的同事,包括我自己也是
3. 学完后,感觉诸多模式极其相似,有困惑,但深知误用之害,应用时有所犹豫
4. 灵活应用模式,甚至不应用模式也能设计出非常优秀的代码,或者说用到了模式而不自知
看到这,突然想起《神雕侠侣》第二十六回,杨过发现独孤求败的剑冢的场景:
杨过提起右首第一柄剑,只见剑下的石上刻有两行小字:
“凌厉刚猛,无坚不摧,弱冠前以之与河朔群雄争锋。”
他将剑放回原处,会起长条石片,见石片下的青石上也刻有两行小字:
“紫薇软剑,三十岁前所用,误伤义不祥,乃弃之深谷。”
看剑下的石刻时,见两行小字道:
“重剑无锋,大巧不工。四十岁前恃之横行天下。”
但见剑下的石刻道:
“四十岁后,不滞于物,草木竹石均可为剑。自此精修,渐进于无剑胜有剑之境。”
一直以来,我都认为学习编程就像习武一样,不同的语言不同方法(C、C++、Java、C#、Python、Erlang等;面向过程、面向对象、函数式编程)对应着不同的门派不同招式(少林、武当、峨眉等)。有的人,执着于某个招式,有的人如独孤求败,令狐冲等,在他们眼中,招式只是一种表现形式。记得我刚接触设计模式时,有个做Java的人居然跟我说C++没有设计模式,在这里我要说的是,我不是损他,而是想说,学习任何事物,都需要弄清楚它能为我们带来什么,为什么要学习它。就像我们公司有些人推荐敏捷一样,我不是鄙视敏捷,相反,我比较喜欢测试驱动开发,喜欢结对编程,但是我觉得敏捷有它适合的领域,也有他不擅长的领域,不是有人说敏捷不是银弹么?至少我觉得做电力系统软件,光有敏捷是不行的,但是可以借鉴敏捷中的部分好思想。
闲话说了一堆,言归正传,在学习模式时,我觉得,最重要的是弄清楚模式适用的领域。