什么是设计模式

在软件的世界,每个开发机构就想一个部落,而模式就是对部落的某种共同记忆的一种具体表现。
<p align="right">————Grady Booch 在《J2EE核心模式》</p>
模式是在特定环境下解决某一问题的方案
<p align="right">————《设计模式》</p>

在工作的过程中一个问题总是反复出现,我们必须一次一次的解决它们,比如 我们应当如何处理接收到的请求?如何将数据转换为对应的指令?如何获取数据?如何显示结果?随着时间的流逝和积累的经验,我们或将优雅或将笨拙的解决这些问题,这些其实就是设计模式。
设计模式记录并规范了这些问题的解决方案,使更多的开发人员能够获取这些来之不易的宝贵经验。模式在本质上是自下而下的,而非自上而下的。它们来源于实践而并非理论,但这并不是说设计模式没有强有力的理论基础。,而是说模式是基于实际的开发人员在实际项目中使用的实际技术。著名的模式专拣Martin Fowler 曾竟说过他是发现模式的而不是发明模式的。因此它们都是我们曾经使用过的技术。
总的来说设计模式其实就是针对软件开发中经常遇到的一些设计问题,总结出来的一套解决方案或者设计思路。

设计模式的历史

谁发明了设计模式? 这是一个很好的问题, 但也有点不太准确。 设计模式并不是晦涩的、 复杂的概念——事实恰恰相反。 模式是面向对象设计中常见问题的典型解决方案。 同样的解决方案在各种项目中得到了反复使用, 所以最终有人给它们起了名字, 并对其进行了详细描述。 这基本上就是模式被发现的历程了。

模式的概念是由克里斯托佛·亚历山大在其著作 《建筑模式语言》 中首次提出的。 本书介绍了城市设计的 “语言”, 而此类 “语言” 的基本单元就是模式。 模式中可能会包含对窗户应该在多高、 一座建筑应该有多少层以及一片街区应该有多大面积的植被等信息的描述。

埃里希·伽玛、 约翰·弗利赛德斯、 拉尔夫·约翰逊和理查德·赫尔姆这四位作者接受了模式的概念。 1994 年, 他们出版了 《设计模式: 可复用面向对象软件的基础》 一书, 将设计模式的概念应用到程序开发领域中。 该书提供了 23 个模式来解决面向对象程序设计中的各种问题, 很快便成为了畅销书。 由于书名太长, 人们将其简称为 “四人组 (Gang of Four, GoF) 的书”, 并且很快进一步简化为 “GoF 的书”。

此后, 人们又发现了几十种面向对象的模式。 ​ “模式方法” 开始在其他程序开发领域中流行起来。 如今, 在面向对象设计领域之外, 人们也提出了许多其他的模式。

设计模式的概要

一个设计模式的核心由四部分组成:名称,问题,解决方案和效果

  • 名称
    名称很重要,几个简短的词便可以表示相当复杂的问题和解决方案。so,名称必须兼顾简洁性和描述性
  • 问题
    无论解决方案如果的优雅(有些的确非常优雅)问题以及问题所发生的环境都是模式的基础。识别问题比使用设计模式更加困难。这正是默写模式的解决方案会被误用或过度使用的原因之一(例如过度使用-单例模式)
  • 解决方案
    解决方案最初适合问题放在一起的,并常用UML类图和交互图进行详细的描述。解决方案通常还包含一份实例代码。虽然模式会给出固定的现成的代码,但是解决方案从来不是简单的复制粘贴代码。就像种地一样,如果我们盲目的照搬书上的步骤,那么很有可能在收获的季节挨饿。以模式为基础,并针对其所使用的各种情形随机应变的方法,才是最实用的方法。虽然问题的基本方案(庄稼生长)是相同(播种,灌溉,收割)的,但我们要考虑各种因素(土壤类型,地理位置,土地的朝向,害虫等等)

Martin Fowler称模式中的解决办法为半成品。也就是说我们必须理解解决方案的概念并实现自己的解决方案。

  • 效果
    设计代码时所做的任何决定都会带来不同的结果。当然我们总是希望能得到令人满意的解决方案。一旦应用某个解决方案,理想情况下它或许会还会非常合适与其他模式协作,不过我们也要提防他可能带来的危险。

模式包含哪些内容?

大部分模式都有正规的描述方式, 以便在不同情况下使用。 模式的描述通常会包括以下部分:

  • 意图部分简单描述问题和解决方案。
  • 动机部分将进一步解释问题并说明模式会如何提供解决方案。
  • 结构部分展示模式的每个部分和它们之间的关系。
  • 在不同语言中的实现提供流行编程语言的代码, 让读者更好地理解模式背后的思想。
    部分模式介绍中还列出其他的一些实用细节, 例如模式的适用性、 实现步骤以及与其他模式的关系。

为什么要使用设计模式

设计模式可以为我们带来哪些好处?如果模式是对问题的定义和对结局方案的描述,那么答案就非常明显了。模式可以为我们解决共同的问题。

当然他还有其他用处

  • 设计模式定义了问题
    有多少次项目在到达同一个阶段时,你发现无法继续下去了?此时你很可能必须以某种方式倒退,或者重构才能继续前进。

通过定义问题,模式可以帮助我们改善设计,有时候找到解决方案的第一步就是认清所面对的问题。

  • 设计模式定义了解决方案
    定义和识别出当前问题后,模式为我们分析了解决方案以及使用该方案能够得到的结果。虽然设计模式无法免除我们自己做出设计决策的责任,但我们至少能够所使用的是可靠且经过测试的技术。
  • 设计模式与编程无关
    模式以面向对象的方式定义对象和解决方案,这意味着许多模式可直接用于多门编程语言。你可以使用(c++,java,php,python等都可以实现并编写自己的解决方案),另外一些模式针对不同的编程语言可能有不同的适用性或效果,但依然是可行的。无论哪种情况,在使用不同的编程语言时,模式都可以帮助我们。构建良好的面向对象设计原则之上的应用可以很轻松的移植到不同的编程语言中,尽管有些问题需要修改。
  • 模式为协作而生
    模式生来就是可生成和可组成的。这意味着我们能应用一种模式并创建适用另一种模式的条件。就好比穿衣搭配,你可以搭配出不同的风格。
  • 设计模式促进优秀设计
    设计模式展示并应用了面向对象设计原则。因此设计模式能在一个具体环境中产生多个特定的解决方案。

关于模式的争议

设计模式自其诞生之初似乎就饱受争议, 所以让我们来看看针对模式的最常见批评吧。

一种针对不完善编程语言的蹩脚解决方案
通常当所选编程语言或技术缺少必要的抽象功能时, 人们才需要设计模式。 在这种情况下, 模式是一种可为语言提供更优功能的蹩脚解决方案。

例如, 策略模式在绝大部分现代编程语言中可以简单地使用匿名 (lambda) 函数来实现。

低效的解决方案
模式试图将已经广泛使用的方式系统化。 许多人会将这样的统一化认为是某种教条, 他们会 “全心全意” 地实施这样的模式, 而不会根据项目的实际情况对其进行调整。

设计模式分类

不同设计模式的复杂程度、 细节层次以及在整个系统中的应用范围等方面各不相同。 我喜欢将其类比于道路的建造: 如果你希望让十字路口更加安全, 那么可以安装一些交通信号灯, 或者修建包含行人地下通道在内的多层互通式立交桥。

最基础的、 底层的模式通常被称为惯用技巧。 这类模式一般只能在一种编程语言中使用。

最通用的、 高层的模式是构架模式。 开发者可以在任何编程语言中使用这类模式。 与其他模式不同, 它们可用于整个应用程序的架构设计。

此外, 所有模式可以根据其意图或目的来分类。主要有以下三类:

创建型模式提供创建对象的机制, 增加已有代码的灵活性和可复用性。创建型模式总共有五种:工厂方法、抽象工厂、单例、建造者(也叫生成器)、原型。

结构型模式介绍如何将对象和类组装成较大的结构, 并同时保持结构的灵活和高效。结构型模式公有七种:适配器、装饰器、代理、外观、桥接、组合、享元

行为模式负责对象间的高效沟通和职责委派。行为模式总共有十一种:策略、模板方法、观察者、迭代器、责任链、命令、备忘录、状态、访问者、中介者、解释器

不要盲从模式

有关模式的另一个问题就是在不必要的或不恰当的使用模式。这样在损害模式的声誉。模式的解决方案很棒,他在引导我们在自认为合适的地方使用它们,而不管他们是否满足需求。
在实际开发中,我们对应用分层,将逻辑从表现层和持久层分离出来。我们会根据情况使用适合的模式。为小型的网站构建表单,我们可能只需要在网页中,编写面向过程的代码就可以了。现在我们并不需要太高的灵活性。不会基于最初的版本大量的扩展,因此无需使用那些用于解决大型项目中所存在问题的模式。相反使用最简单的方法完成任务。更方便一点。

参考书籍:
深入PHP 面向对象、模式与实践
深入设计模式

Last modification:June 2nd, 2020 at 04:20 pm