前言
随着编程经验的增加,慢慢的发现基本的语法知识已经掌握,也能解决一些问题。但,总感觉自己编写的代码质量不高,可维护性不强,为了解决这个问题,就看了一些关于编程风格、编程规范、设计模式等方面的书籍和文章。总的来说,收获颇多。本文旨在对设计模式进行粗浅的介绍,后续会陆续介绍JS里常用的设计模式。
1.为什么使用模式?
模式是一种可复用的解决方案,可用于解决软件设计中遇到的常见问题。那么设计模式会给我们的编程实践带来什么助益呢?下面就是设计模式的优点:
-
模式是已经验证的解决方案
设计模式(Design pattern)是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结,它们为解决软件开发中遇到的问题提供了可靠的方法。
-
模式很容易被复用
模式是被验证过的解决方案,可以立即使用,可以结合自己的开发需求使用这些模式。
-
模式富有表达力
使用设计模式是为了可重用代码,让代码更容易被他人理解、保证代码可靠性。
-
复用模式有助于防止在应用程序开发过程中小问题引发大问题
当我们在已验证的模式基础上开发代码时,可以在代码结构上花费更少的精力,更多的关注整体解决方案。因为模式支持我们用更结构化、更有组织性的方式编写代码,从而避免以后因代码的整洁性问题而重构代码。
-
模式可以提供通用的解决方案,并且其记录方式不需要与某个特定问题挂钩
模式是通用性的,不局限于具体的项目和编程语言。
-
某些模式确实能够通过避免代码复用来减少代码的总体资源占用量
某些模式可以更多的复用代码,减少代码量,而且代码结构也更加紧凑和严密,具有更强的可读性和可维护性。
-
模式添加到开发人员的词汇中,会使沟通更快速
-
经常使用的模式可以逐步改进,因为其他开发人员会及时反馈
2.何为设计模式?
设计模式有其自身的要求与规则,并不是每一种算法、最佳实践或解决方案都代表一种完整的模式。在尚未被审查之前,设计模式社区通常不会认定它是一种真正的设计模式。即使某种内容外观看起来符合模式的标准,但这依然需要经过一段时间的审查和多人的测试,只有这样才能成最终的设计模式。
设计模式应该是一种流程,也是一种事物,是一种能够创建“事物”的流程。
原始模式:一种尚未通过“模式”测试的设计模式。原始模式是编程开发人员分享的特殊解决方案,但尚未经过检验,还有就是原始模式最初非常简陋,仅仅只是一个简单描述。
一个优秀的设计模式应该有哪些特征呢?
- 解决特殊问题
模式不应该只是获取原则或策略,它们需要获取解决方案。这是作为一种优秀模式不可或缺的要素。
- 没有显而易见的解决方案
解决问题的技术基本来自众所周知的基本原则。好的设计模式会间接的提高解决方案--这被认为是解决与设计相关的最具有挑战性问题的必要方法。
- 描述业经验证的概念
设计模式需要证明它们的作用和描述的一致,并且没有证明这一点,就不能考虑该设计。
- 描述一种关系
在某些情况下,看起来可能是一种模式描述了一种类型的模块。尽管一种实现看起来也是这样,但对模式的正式表述必须能够更深入地理解它与代码关系的系统结构和机制。
我们会想当然的认为一种不符合设计准则的原始模式是不值得学习的,然而并不是如此。很多原始模式也是非常有用的,也是可以解决不少问题的,只是缺少验证而已。在编程过程中,我们需要发挥自己的决断力,优雅的选择合适的模式解决问题。
成为有效模式的其中一个附加要求是,它们展示一些反复出现的现象。这通常被限定在至少三个领域内,被称为三法则:
- 适合性
- 实用性
- 适用性
3.设计模式的结构
上面介绍了一个优秀的设计模式需要满足的要求,那么怎么才能完成一个设计模式的编写呢?传统上,一种设计模式最初是以一种规则的形式呈现的,该规则建立下面这样的关系:
- 上下文
- 上下文里产生的原件系统
- 解决原件在上下文中自身问题的配置
下面是一种设计模式应该包括的内容:
- 模式名称
- 描述
- 上下文大纲:模式的使用场景
- 问题陈述
- 解决方案
- 设计
- 实现
- 插图
- 示例
- 辅助条件
- 关系:与其他模式的关系
- 已知的用法
- 讨论:对该模式优势的想法
设计模式在规划和设计阶段可能要花费大量的初始成本,但这会对我们的后续开发工作带来很大的便利,前期投入是非常值得的。但不要为了编写新模式而编写,要多选用现有的已经验证过的优秀设计模式,也可以在现有模式上进行二次开发,满足自己的需求。
4.编写设计模式
编写优秀的设计模式是一项具有挑战性的任务。很多时候当我们认为某段程序正在使用某种模式时,或许它只是偶然性的像一种模式而已,我们会发现我们只是在查看遵循好的原则和设计实践的代码,而这些原则和设计实践可能偶然会与模式的规则发生重叠。没有交互和明确规则的解决方案就不是模式。
在进行编写设计模式之时,下面一些要点是应该时刻牢记的:
- 模式的实用性有多少?
- 牢记最佳实践
- 设计模式对于用户来说是透明的
- 要牢记独创性在模式设计中不是重点
- 模式需要一批有说服力的示例
编写模式是主要在创建通用、具体及有用的设计方面寻找一种平衡,要努力确保所编写的模式能够覆盖最广泛的应用领域。
5.反模式
模式代表着最佳实践,那么反模式就是一种糟糕的实践,是我们需要极力避免的。
反模式是:
- 描述一种针对某个特定问题的不良解决方案,该方案会导致糟糕情况发生;
- 描述如何摆脱前述的糟糕情况以及如何创造好的解决方案。
按照优秀的设计模式开发项目,可以使程序简洁、优雅、易维护,而反模式会为我们带来有些问题,在日常开发过程中要避免使用反模式。JavaScript中的一些反模式示例如下:
- 在全局上下文中定义大量的变量污染全局命名空间
- 向setTimeout或setInterval传递字符串而不是函数,触发eval()调用
- 修改Object类的原型
- ……
6.设计模式分类
常见的设计模式有很多,它们虽然都是为了给特定的问题提供解决方案,但依然可以从它们的异同点出发,把它们归类。大致为:
- 创建型设计模式
创建型设计模式专注于处理对象创建机制,以适合给定情况的方式来创建对象。创建对象的基本方法可能导致项目复杂性增加,而这些模式旨在通过控制创建过程来解决这种问题。
包括:Constructor(构造器)、Factory(工厂)、Abstract(抽象)、Prototype(原型)、Singleton(单例)和Builder(生成器)等。
- 结构型设计模式
结构型模式与对象组合有关,通常可以用于找出不同对象之间建立关系的简单方式。其有助于确保在系统某一部分发生变化时,系统的整个结构不需要同时改变,对于不便因某一特定目的而改变的部分,其也能帮它们完成重组。
包括:Decorator(装饰者)、Facade(外观)、Flyweight(享元)、Adapter(适配器)、和Proxy(代理)等。
- 行为型设计模式
行为模式专注于改善或简化系统中不同对象之间的通信。
包括:Iterator(迭代器)、Mediator(中介者)、Observer(观察着)和Vistior(访问者)等。
本文大致介绍了设计模式的概念、用途、意义及规则等知识点,并未对具体的设计模式进行详尽的描述,只是为了给大家勾勒出设计模式的大致轮廓,后续的文章会详细探讨这些设计模式的应用场景和使用方式。