在四人(Gang of Four,GoF)的那本设计模式的书出版20年后,重新审视设计模式,书中的23种设计模式,真的只是23种使用指针的方法吗?对我们这个时代是否还有指导意义?(来自湾区日报对本文的评论) 二十年前,软件设计领域的四位大师(GoF,“四人”,又称Gang of Four,即Erich Gamma, Richard Helm, Ralph Johnson & John Vlissides)通过论著《设计模式:可复用面向对象软件的基础》阐述了设计模式领域的开创性成果。 当时软件设计仍以C++与Smalltalk为主流,同时利用时间设计理念(例如强调继承)进行编写,但抛开历史的局限、他们已经为业界带来一场规模可观的浪潮。然而历史告诉我们,任何言过其实且无法在实践层面履行承诺的“浪潮”都必然令人失望,并最终遭到淘汰。如今二十年弹指一挥,我们应当重新审视当初提出的23种模式(其中一些亦可被称为变种),考虑它们与二十年来愈发成熟的编程语言还能否契合或者说并发出新的火花。 模式:究竟有着怎样的作用?在模式“运动”发展之初,人们还将其视为一种新鲜的概念,但却很少花时间探讨其究竟是什么。模式就是模式——它来自我们阅读的参考书籍、体现在实践层面的代码当中,亦充斥于我们的日常工作之内。直观地讲,我们似乎意识到自己能够运用这些知识,亦欣赏头脑中孕育出的种种新型模式思路。 Gang of Four(简称GOF)似乎从一开始就将模式视为一种艺术/科学;在论著的最后一章(遗憾的是,读者们大多直接将其忽略),他们指出:
但需要强调的是,实际情况在于:这本书中的模式设计理念尚未彻底完成。我在DevelopMentor上结识的一位朋友将设计模式称为“23种指针使用方法”。好吧,似乎也有道理。 同样的,当管理层/高管团队将这本书甩给新手开发者并希望他们通过阅读实现技能“升级”时,结果也肯定会让他们深感失望。 然而,收益仍是真实存在的,而且更加微妙:
诚然,GOF的这本论著引发了一股浪潮,而这股模式浪潮又催生出远超GOF提出的23种初始模式之外的思维结晶。然而,事情亦开始朝着更为抽象及高层的方向推进,模式开始以“模式语言”的姿态出现,并反过来创造出“元模式”。而后人们开始记录其中的负面因素,并将其称为“反模式”。 一旦人们意识到这一议题能够带来经济收益,相关出版物亦开始不断涌现。 各类出版商不断推出“模式“方面的书籍——但这些出版物几乎根本不涉及GOF提出的原始模型。模式书籍成了”可复用代码“(而非‘可复用设计元素’)的代名词。IDE供应商开始寻找可行途径,希望将多种模式整合为代码生成器。同样莫名其妙的是,模式也开始成为UML及其它设计符号的载体,其目标被误解成弄清如何在UML当中找到与模式相对应的可复用设计模板。 与众多炒作对象一样,模式成为一种潮流,但人们并不知道其核心吸引力究竟是什么。在这种情况下,模式概念显然没办法满足人们的预期。 到2000年中叶,模式开始成为一种负面概念,当时的宣传导向则转为“捣毁“模式——即强调模式属于“糟糕语言”加“原始思路”再加上“被归入优秀语言”的综合体。 换言之,模式显然毫无实际用处。 但是……模式这一称谓仍然不断出现,直到今天我们亦在大量使用。为什么?GOF实际早在1995年就对此做出了预言(同样来自书中最后一章):
(是的,他们早在业界将其视为时尚之前,就已经提出了重构的必要性。) 最重要的是,他们还准确预测出了模式弊端所引发的问题:
很多短视的从业者将模式视为“解决方案”,并一窝蜂地希望找到可复用代码,但却忘了(或者刻意不去想)“理由”是什么。作为结果,他们往往会犯下一些非常愚蠢——但本该能够轻易被预测——的错误。 模式是什么?多年以来,围绕这一议题出现了无数讨论,但我想用下面这句话对其加以概括: 模式是一套立足于特定背景,且拥有一整套可预测结果的解决方案。 就是这样。没什么神奇、神秘或者超学术性质的元素。如果大家能够对元组的全部四个部分加以描述,那么这就是一种模式。把它写下来再加以发布。 一旦发现了彼此之间的共同点,我们就可以从中找到共性所在,而后为其选定一个合适的名称并加入到通用词汇表当中。 Gang of Four发布了23条这样的模式,当然模式的实际数量远不止如此。大部分模式都极具实用性,但实用性最出众的还是这最初的23条——因为它们涵盖了众多不同类型的编程语言。(模式业界后来创造出了所谓‘成语’,其只适用于特定的语言。因此来自C++的‘资源获取即初始化(简称RAII)’概念就成了与C++语言紧密相关的‘成语’,而并非真正的模式。) 我们为什么要进行讨论?不过最后一句又带来新的问题:模式业界投入了太多时间进行讨论,包括模式本身、特定对象是否属于模式乃至某种特定代码片段到底属于哪种模式的具体实现方式等等。 在这方面我们有两种基本思路:
最后需要强调的是,模式的拥护者本身可能正是导致模式毁灭的导火索——但事情仍然还有转机。 拨乱反正我想在模式概念首次出现的二十年后,是时候对其进行重新讨论了。我无法想象自己如何凭一己之力重现这样的浪潮,但至少我可以对过往的积累加以整理,留其精华而去其糟粕,并期待将其引入二十一世纪大家所熟悉的各类主流语言。在这一过程中,也许我们还会发现更多新的模式,我亦会从中选择部分合适的与大家分享。 在未来几个月中,我将立足于“现代世界”对这23条元祖模式进行回顾,并采取我个人最喜爱的审视方式(问题/解决方案/背景/结果)。我不会直接引用太多来自Gang of Four论著中的原文,因为这会构成侵权行为——但我强烈建议大家买一本自行阅读,并借此思考我给出的结论是否合理。另外,我还会以部分现代语言为基础探讨各类模式的实现方式,具体包括:C++、C#、Java、Swift、F#、Scala以及JavaScript等等。我绝对不是世界上最聪明的家伙,所以肯定没法以最为纯熟的方式运用这些语言并探讨其相关成语适用性——因此请大家积极发表意见与建议,以帮助我完成修改/更正。另外,我也希望能够与大家共同涵盖全部主流(可能也会包含部分并不那么流行但有助于指导效果的语言)语言。 这些工作都需要时间,所以请大家多多包涵。我会尽快再发布一篇博文讨论具体细节,而在此期间希望大家能买一本GOF的《设计模式:可复用面向对象软件的基础》来读读。 后记作者做的工作非常有意思,在我和他发邮件申请本文的版权的同时,他也诚挚的邀请中国的开发者能和他做这个有意思的探索。的确,设计模式已经存在了几十年,很多东西已经不再适用,但这些模式已经被当做开发领域的金玉良言。是时候来反思了! 点击阅读原文链接,查看作者对Java的单例模式的论述,如果感兴趣,欢迎评论留言,和Ted一起回顾设计模式。 |