#1. 代码设计模式
# 我们写代码到底是在写什么?
我们写项目其实就是写模块然后设计它们之间的沟通,设计模式说白了就是帮助我们更好的设计模块, 更好的组织它们之间的沟通。
# 设计模式扮演的角色
-
帮助我们组织模块
通过一些设计模式,组织模块间的组成结构
-
帮助我们设计沟通
有的设计模式可以帮助我们设计模块间如何沟通
-
提高代码质量
通过设计模式,让代码更加优雅
# 设计原则
-
开闭原则
我们的程序要对扩展开放,对修改关闭;我们的程序要给具体使用的时候扩展的接口,但是在具体使用的时候不能让其修改我们的源码, 也就是说我们不用修改源码就能扩展功能,像 vue,react 等都有扩展的接口。
-
单一职责原则
我们的模块只做一件事情,模块的职责越单一越好。
-
依赖倒置原则
我们的上层模块不要依赖与具体的下层模块,应该依赖于抽象
假如下面是一套点餐系统,我们在上层和下层之间加一个抽象层;下层如何变动都不会影响到上层,只需更改抽象层即可。
<span style="background-color:#282c34"><span style="color:#2c3e50"><span style="color:#cccccc"><code><span style="color:#999999">// 具体层</span>
<span style="color:#cc99cd">function</span> <span style="color:#f08d49">Food1</span><span style="color:#cccccc">(</span><span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span><span style="color:#cccccc">}</span>
<span style="color:#cc99cd">function</span> <span style="color:#f08d49">Food2</span><span style="color:#cccccc">(</span><span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span><span style="color:#cccccc">}</span>
<span style="color:#cc99cd">function</span> <span style="color:#f08d49">Food3</span><span style="color:#cccccc">(</span><span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span><span style="color:#cccccc">}</span><span style="color:#999999">// 抽象层</span>
<span style="color:#cc99cd">function</span> <span style="color:#f08d49">resturn</span><span style="color:#cccccc">(</span>food<span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span><span style="color:#cc99cd">var</span> list <span style="color:#67cdcc">=</span> <span style="color:#cccccc">{</span>food1<span style="color:#67cdcc">:</span> <span style="color:#cc99cd">new</span> <span style="color:#f8c555">Food1</span><span style="color:#cccccc">(</span><span style="color:#cccccc">)</span><span style="color:#cccccc">,</span>food2<span style="color:#67cdcc">:</span> <span style="color:#cc99cd">new</span> <span style="color:#f8c555">Food2</span><span style="color:#cccccc">(</span><span style="color:#cccccc">)</span><span style="color:#cccccc">,</span>food3<span style="color:#67cdcc">:</span> <span style="color:#cc99cd">new</span> <span style="color:#f8c555">Food3</span><span style="color:#cccccc">(</span><span style="color:#cccccc">)</span><span style="color:#cccccc">}</span><span style="color:#cc99cd">return</span> list<span style="color:#cccccc">[</span>food<span style="color:#cccccc">]</span>
<span style="color:#cccccc">}</span><span style="color:#999999">// 上层</span>
<span style="color:#cc99cd">function</span> <span style="color:#f08d49">order</span><span style="color:#cccccc">(</span>food<span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span><span style="color:#cc99cd">return</span> <span style="color:#f08d49">resturn</span><span style="color:#cccccc">(</span>food<span style="color:#cccccc">)</span>
<span style="color:#cccccc">}</span>
</code></span></span></span>
- 接口隔离原则
我们的接口要细化,功能要单一,一个接口不要调用太多方法,使其能力单一,听起来像单一职责原则;但是 2 者的关注点不同, 单一职责原则主要关注于模块本身,接口隔离原则关注于接口;我们尽量细化接口,每个接口做的事情尽量单一化。
- 迪米特法则
我们让 2 个对象之间产生沟通,我们最好让 2 个对象之间知道的越少越好,没必要 2 者之间非常的了解;我们的中介者模式是一个很好体现迪米特法则的设计模式,中介者模式让 2 个对象之间没必要直接的沟通,如果直接沟通需要了解 2 者之间的 api 和彼此的调用方式,这个时候我们可以采用一个中介者来转达我们的需求,而不用彼此知道
- 里氏替换原则
它主要关注于继承,它的意义是任何使用父类的地方都可以用子类去替换,直白的说我们子类继承父类的时候,我们的子类必须完全保证继承父类的属性和方法,这样的话父类使用的地方,子类可以进行替换
后面学习到设计模式都是在体现这些设计原则
# 设计模式的分类
- 创建型
这些设计模式可以帮助我们优雅地创建对象
- 结构型
帮助我们优雅地设计代码结构
- 行为型
模块之间行为的模式总结,帮助我们组织模块行为
- 技巧型
一些帮助我们优化代码的技巧
# 创建型
-
工厂模式-大量创建对象
-
单例模式-全局只能有我一个
-
建造者模式-精细化组合对象
-
原型模式-javaScript 的灵魂
# 结构型
-
外观模式-给你的一个套餐
-
适配器模式-用适配代替更改
-
装饰者模式-更优雅地扩展需求
-
享元模式-共享来减少数量
-
桥接模式-独立出来,然后再对接过去
# 行为型
-
观察者模式-我作为第三方转发
-
状态模式-用状态代替判断
-
策略模式-算法工厂
-
职责链模式-像生产线一样组织模块
-
命令模式-用命令去解耦
-
迭代器模式-告别 for 循环
# 技巧模式
-
链模式-链式调用
-
委托模式-让别人代替你收快递
-
数据访问模式-一个方便的数据管理器
-
惰性模式-我要搞机器学习(第一次执行完后把状态记录下来)
-
等待者模式-等你们都回来再吃饭
#2. 封装对象
创建型设计模式到底是怎么样使用的,利用创建型设计模式更好的封装代码更好的创建对象
封装的目的?
-
定义的变量不会污染到外部
-
能够作为一个模块调用
-
遵循开闭原则
什么是好的封装?
-
变量外部不可见
-
调用接口使用
-
留出扩展接口
#2.1 封装对象时的设计模式
# 创建一个对象的模式
-
工厂模式
目的:方便我们大量创建对象
应用场景:当某一个对象需要经常创建的时候
-
建造者模式
目的:需要组合出一个全局对象
应用场景:当要创建单个、庞大的组合对象时
# 保障对象全局只有一个
-
单例模式
目的:需要确保全局只有一个对象
应用场景:为了避免重复新建,避免多个对象存在相互干扰
#2.2 基本结构
# 工厂模式的基本结构
<span style="background-color:#282c34"><span style="color:#2c3e50"><span style="color:#cccccc"><code><span style="color:#cc99cd">function</span> <span style="color:#f08d49">Factory</span> <span style="color:#cccccc">(</span>type<span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span><span style="color:#cc99cd">switch</span> <span style="color:#cccccc">(</span>type<span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span><span style="color:#cc99cd">case</span> <span style="color:#7ec699">'type1'</span><span style="color:#cc99cd">return</span> <span style="color:#cc99cd">new</span> <span style="color:#f8c555">Type1</span><span style="color:#cccccc">(</span><span style="color:#cccccc">)</span><span style="color:#cc99cd">case</span> <span style="color:#7ec699">'type2'</span><span style="color:#cc99cd">return</span> <span style="color:#cc99cd">new</span> <span style="color:#f8c555">Type2</span><span style="color:#cccccc">(</span><span style="color:#cccccc">)</span><span style="color:#cc99cd">case</span> <span style="color:#7ec699">'type3'</span><span style="color:#cc99cd">return</span> <span style="color:#cc99cd">new</span> <span style="color:#f8c555">Type3</span><span style="color:#cccccc">(</span><span style="color:#cccccc">)</span><span style="color:#cccccc">}</span>
<span style="color:#cccccc">}</span>
</code></span></span></span>
工厂模式就是写一个方法,只需调用这个方法,就能拿到你要的对象
# 建造者模式的基本结构
<span style="background-color:#282c34"><span style="color:#2c3e50"><span style="color:#cccccc"><code><span style="color:#999999">// 模块1</span>
<span style="color:#cc99cd">function</span> <span style="color:#f08d49">Mode1</span><span style="color:#cccccc">(</span><span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span><span style="color:#cccccc">}</span>
<span style="color:#999999">// 模块2</span>
<span style="color:#cc99cd">function</span> <span style="color:#f08d49">Mode2</span><span style="color:#cccccc">(</span><span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span><span style="color:#cccccc">}</span>
<span style="color:#999999">// 最终使用的类</span>
<span style="color:#cc99cd">function</span> <span style="color:#f08d49">Final</span><span style="color:#cccccc">(</span><span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span><span style="color:#cc99cd">this</span><span style="color:#cccccc">.</span>mode1 <span style="color:#67cdcc">=</span> <span style="color:#cc99cd">new</span> <span style="color:#f8c555">Model</span><span style="color:#cccccc">(</span><span style="color:#cccccc">)</span><span style="color:#cc99cd">this</span><span style="color:#cccccc">.</span>mode2 <span style="color:#67cdcc">=</span> <span style="color:#cc99cd">new</span> <span style="color:#f8c555">Mode2</span><span style="color:#cccccc">(</span><span style="color:#cccccc">)</span>
<span style="color:#cccccc">}</span>
</code></span></span></span>
把一个复杂的类各个部分,拆分成独立的类,然后再最终类里组合到一块,final 为最终给出去的类
# 单例模式的基本结构
单例模式的做法不是很固定,我们更重要的记住是保证全局只有一个对象的思想
<span style="background-color:#282c34"><span style="color:#2c3e50"><span style="color:#cccccc"><code><span style="color:#999999">// 作为单例实例化的对象</span>
<span style="color:#cc99cd">let</span> <span style="color:#f08d49">SingLeton</span> <span style="color:#67cdcc">=</span> <span style="color:#cc99cd">function</span><span style="color:#cccccc">(</span>name<span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span><span style="color:#cc99cd">this</span><span style="color:#cccccc">.</span>name <span style="color:#67cdcc">=</span> name
<span style="color:#cccccc">}</span>
<span style="color:#999999">/*
在SingLeton挂在一个getInstance方法,只能通过getInstance方法来获取
SingLeton的实力化对象
*/</span>
SingLeton<span style="color:#cccccc">.</span><span style="color:#f08d49">getInstance</span> <span style="color:#67cdcc">=</span> <span style="color:#cc99cd">function</span><span style="color:#cccccc">(</span>name<span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span><span style="color:#cc99cd">if</span> <span style="color:#cccccc">(</span><span style="color:#cc99cd">this</span><span style="color:#cccccc">.</span>instance<span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span><span style="color:#cc99cd">return</span> <span style="color:#cc99cd">this</span><span style="color:#cccccc">.</span>instance<span style="color:#cccccc">}</span><span style="color:#cc99cd">return</span> <span style="color:#cccccc">(</span><span style="color:#cc99cd">this</span><span style="color:#cccccc">.</span>instance <span style="color:#67cdcc">=</span> <span style="color:#cc99cd">new</span> <span style="color:#f8c555">SingLeton</span><span style="color:#cccccc">(</span>name<span style="color:#cccccc">)</span><span style="color:#cccccc">)</span>
<span style="color:#cccccc">}</span>
</code></span></span></span>
通过定义一个方法,使用时只允许通过此方法拿到存在内部的同一实例化对象
#2.3 应用示例
# 工厂模式的示例
实现一个多彩的弹窗?
需求:弹窗有多种,它们之间存在内容和颜色上的差异
<span style="background-color:#282c34"><span style="color:#2c3e50"><span style="color:#cccccc"><code><span style="color:#cccccc">;</span><span style="color:#cccccc">(</span><span style="color:#cc99cd">function</span><span style="color:#cccccc">(</span><span style="color:#f8c555">ROOT</span><span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span><span style="color:#999999">// 消息弹性</span><span style="color:#cc99cd">function</span> <span style="color:#f08d49">infoPop</span><span style="color:#cccccc">(</span><span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span><span style="color:#cccccc">}</span><span style="color:#999999">// 确认弹窗</span><span style="color:#cc99cd">function</span> <span style="color:#f08d49">confirmPop</span><span style="color:#cccccc">(</span><span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span><span style="color:#cccccc">}</span><span style="color:#999999">// 取消弹窗</span><span style="color:#cc99cd">function</span> <span style="color:#f08d49">cancelPop</span><span style="color:#cccccc">(</span><span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span><span style="color:#cccccc">}</span><span style="color:#999999">// 弹窗工厂</span><span style="color:#cc99cd">function</span> <span style="color:#f08d49">pop</span><span style="color:#cccccc">(</span>type<span style="color:#cccccc">,</span> content<span style="color:#cccccc">,</span> color<span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span><span style="color:#cc99cd">switch</span> <span style="color:#cccccc">(</span>type<span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span><span style="color:#cc99cd">case</span> <span style="color:#7ec699">'infoPop'</span><span style="color:#67cdcc">:</span><span style="color:#cc99cd">return</span> <span style="color:#cc99cd">new</span> <span style="color:#f8c555">infoPop</span><span style="color:#cccccc">(</span>content<span style="color:#cccccc">,</span> color<span style="color:#cccccc">)</span><span style="color:#cc99cd">case</span> <span style="color:#7ec699">'confirmPop'</span><span style="color:#67cdcc">:</span><span style="color:#cc99cd">return</span> <span style="color:#cc99cd">new</span> <span style="color:#f8c555">confirmPop</span><span style="color:#cccccc">(</span>content<span style="color:#cccccc">,</span> color<span style="color:#cccccc">)</span><span style="color:#cc99cd">case</span> <span style="color:#7ec699">'confircancelPopmPop'</span><span style="color:#67cdcc">:</span><span style="color:#cc99cd">return</span> <span style="color:#cc99cd">new</span> <span style="color:#f8c555">cancelPop</span><span style="color:#cccccc">(</span>content<span style="color:#cccccc">,</span> color<span style="color:#cccccc">)</span><span style="color:#cccccc">}</span><span style="color:#cccccc">}</span><span style="color:#f8c555">ROOT</span><span style="color:#cccccc">.</span>pop <span style="color:#67cdcc">=</span> pop
<span style="color:#cccccc">}</span><span style="color:#cccccc">)</span><span style="color:#cccccc">(</span>window<span style="color:#cccccc">)</span>
<span style="color:#999999">// 根据传入不同的参数来,来弹出不同的弹窗</span>
<span style="color:#f08d49">pop</span><span style="color:#cccccc">(</span><span style="color:#7ec699">'infoPop'</span><span style="color:#cccccc">,</span> <span style="color:#7ec699">'开始'</span><span style="color:#cccccc">,</span> <span style="color:#7ec699">'white'</span><span style="color:#cccccc">)</span>
</code></span></span></span>
上面这种写法有个弊端就是不能 new pop,当用户用 new 关键词就不适用了
<span style="background-color:#282c34"><span style="color:#2c3e50"><span style="color:#cccccc"><code><span style="color:#cccccc">;</span><span style="color:#cccccc">(</span><span style="color:#cc99cd">function</span><span style="color:#cccccc">(</span><span style="color:#f8c555">ROOT</span><span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span><span style="color:#cc99cd">function</span> <span style="color:#f08d49">pop</span><span style="color:#cccccc">(</span>type<span style="color:#cccccc">,</span> content<span style="color:#cccccc">,</span> color<span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span><span style="color:#cc99cd">if</span> <span style="color:#cccccc">(</span><span style="color:#cc99cd">this</span> <span style="color:#cc99cd">instanceof</span> <span style="color:#f8c555">pop</span><span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span><span style="color:#cc99cd">var</span> s <span style="color:#67cdcc">=</span> <span style="color:#cc99cd">this</span><span style="color:#cccccc">[</span>type<span style="color:#cccccc">]</span><span style="color:#cccccc">(</span>content<span style="color:#cccccc">,</span> color<span style="color:#cccccc">)</span><span style="color:#cc99cd">return</span><span style="color:#cccccc">}</span> <span style="color:#cc99cd">else</span> <span style="color:#cccccc">{</span><span style="color:#cc99cd">return</span> <span style="color:#cc99cd">new</span> <span style="color:#f8c555">pop</span><span style="color:#cccccc">(</span>type<span style="color:#cccccc">,</span> content<span style="color:#cccccc">,</span> color<span style="color:#cccccc">)</span><span style="color:#cccccc">}</span><span style="color:#cccccc">}</span>pop<span style="color:#cccccc">.</span>prototype<span style="color:#cccccc">.</span><span style="color:#f08d49">infoPop</span> <span style="color:#67cdcc">=</span> <span style="color:#cc99cd">function</span><span style="color:#cccccc">(</span><span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span><span style="color:#cccccc">}</span>pop<span style="color:#cccccc">.</span>prototype<span style="color:#cccccc">.</span><span style="color:#f08d49">confirmPop</span> <span style="color:#67cdcc">=</span> <span style="color:#cc99cd">function</span><span style="color:#cccccc">(</span><span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span><span style="color:#cccccc">}</span>pop<span style="color:#cccccc">.</span>prototype<span style="color:#cccccc">.</span><span style="color:#f08d49">cancelPop</span> <span style="color:#67cdcc">=</span> <span style="color:#cc99cd">function</span><span style="color:#cccccc">(</span><span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span><span style="color:#cccccc">}</span><span style="color:#f8c555">ROOT</span><span style="color:#cccccc">.</span>pop <span style="color:#67cdcc">=</span> pop
<span style="color:#cccccc">}</span><span style="color:#cccccc">)</span><span style="color:#cccccc">(</span>window<span style="color:#cccccc">)</span><span style="color:#f08d49">pop</span><span style="color:#cccccc">(</span><span style="color:#7ec699">'infoPop'</span><span style="color:#cccccc">,</span> <span style="color:#7ec699">'开始'</span><span style="color:#cccccc">,</span> <span style="color:#7ec699">'white'</span><span style="color:#cccccc">)</span>
</code></span></span></span>
jQuery 源码示例
需求:jQuery 需要操作 dom,每个 dom 都是一个 jq 对象
总结:工厂模式就是要把我们要暴露的对象,真正要实例化的对象先封装到函数的内部,然后我们只暴露一个工厂方法,使用者通过这个工厂方法 来获取我们实例话的对象,它的优势方便我们大量的创建对象。
# 建造者模式的示例
编写一个编辑器插件
需求:有一个编辑器插件,初始化的时候需要配置大量参数,而且内部功能很多
<span style="background-color:#282c34"><span style="color:#2c3e50"><span style="color:#cccccc"><code><span style="color:#999999">// 最终类</span>
<span style="color:#cc99cd">function</span> <span style="color:#f08d49">Editor</span><span style="color:#cccccc">(</span><span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span><span style="color:#cc99cd">this</span><span style="color:#cccccc">.</span>intt <span style="color:#67cdcc">=</span> <span style="color:#cc99cd">new</span> <span style="color:#f8c555">initHTML</span><span style="color:#cccccc">(</span><span style="color:#cccccc">)</span><span style="color:#cc99cd">this</span><span style="color:#cccccc">.</span>fontControll <span style="color:#67cdcc">=</span> <span style="color:#cc99cd">new</span> <span style="color:#f8c555">fontControll</span><span style="color:#cccccc">(</span><span style="color:#cccccc">)</span><span style="color:#cc99cd">this</span><span style="color:#cccccc">.</span>stateControll <span style="color:#67cdcc">=</span> <span style="color:#cc99cd">new</span> <span style="color:#f8c555">stateControll</span><span style="color:#cccccc">(</span><span style="color:#cccccc">)</span>
<span style="color:#cccccc">}</span><span style="color:#999999">// 初始化html的类,最终渲染成dom</span>
<span style="color:#cc99cd">function</span> <span style="color:#f08d49">initHTML</span><span style="color:#cccccc">(</span><span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span><span style="color:#cccccc">}</span>
<span style="color:#999999">// 初始化控制样式的方法</span>
initHTML<span style="color:#cccccc">.</span>prototype<span style="color:#cccccc">.</span><span style="color:#f08d49">initStyle</span> <span style="color:#67cdcc">=</span> <span style="color:#cc99cd">function</span><span style="color:#cccccc">(</span><span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span><span style="color:#cccccc">}</span>
<span style="color:#999999">// 初始化渲染成dom的方法</span>
initHTML<span style="color:#cccccc">.</span>prototype<span style="color:#cccccc">.</span><span style="color:#f08d49">renderDom</span> <span style="color:#67cdcc">=</span> <span style="color:#cc99cd">function</span><span style="color:#cccccc">(</span><span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span><span style="color:#cccccc">}</span><span style="color:#999999">// 改变字体颜色大小的类</span>
<span style="color:#cc99cd">function</span> <span style="color:#f08d49">fontControll</span><span style="color:#cccccc">(</span><span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span><span style="color:#cccccc">}</span>
<span style="color:#999999">// 控制颜色的方法</span>
fontControll<span style="color:#cccccc">.</span>prototype<span style="color:#cccccc">.</span><span style="color:#f08d49">changeColor</span> <span style="color:#67cdcc">=</span> <span style="color:#cc99cd">function</span><span style="color:#cccccc">(</span><span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span><span style="color:#cccccc">}</span>
<span style="color:#999999">// 控制字体大小的方法</span>
fontControll<span style="color:#cccccc">.</span>prototype<span style="color:#cccccc">.</span><span style="color:#f08d49">changeFontsize</span> <span style="color:#67cdcc">=</span> <span style="color:#cc99cd">function</span><span style="color:#cccccc">(</span><span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span><span style="color:#cccccc">}</span><span style="color:#999999">// 改变状态类,为了前进后退</span>
<span style="color:#cc99cd">function</span> <span style="color:#f08d49">stateControll</span><span style="color:#cccccc">(</span><span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span><span style="color:#cc99cd">this</span><span style="color:#cccccc">.</span>state <span style="color:#67cdcc">=</span> <span style="color:#cccccc">[</span><span style="color:#cccccc">]</span> <span style="color:#999999">//存储状态</span><span style="color:#cc99cd">this</span><span style="color:#cccccc">.</span>nowstate <span style="color:#67cdcc">=</span> <span style="color:#f08d49">0</span> <span style="color:#999999">//状态指针</span>
<span style="color:#cccccc">}</span>
<span style="color:#999999">//保存状态的方法</span>
stateControll<span style="color:#cccccc">.</span>prototype<span style="color:#cccccc">.</span><span style="color:#f08d49">saveState</span> <span style="color:#67cdcc">=</span> <span style="color:#cc99cd">function</span><span style="color:#cccccc">(</span><span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span><span style="color:#cccccc">}</span>
<span style="color:#999999">//回滚状态的方法</span>
stateControll<span style="color:#cccccc">.</span>prototype<span style="color:#cccccc">.</span><span style="color:#f08d49">saveBack</span> <span style="color:#67cdcc">=</span> <span style="color:#cc99cd">function</span><span style="color:#cccccc">(</span><span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span><span style="color:#cc99cd">var</span> state <span style="color:#67cdcc">=</span> <span style="color:#cc99cd">this</span><span style="color:#cccccc">.</span>state<span style="color:#cccccc">[</span><span style="color:#cc99cd">this</span><span style="color:#cccccc">.</span>nowstate <span style="color:#67cdcc">-</span> <span style="color:#f08d49">1</span><span style="color:#cccccc">]</span><span style="color:#cc99cd">this</span><span style="color:#cccccc">.</span>fontControll<span style="color:#cccccc">.</span><span style="color:#f08d49">changeColor</span><span style="color:#cccccc">(</span>state<span style="color:#cccccc">.</span>color<span style="color:#cccccc">)</span><span style="color:#cc99cd">this</span><span style="color:#cccccc">.</span>fontControll<span style="color:#cccccc">.</span><span style="color:#f08d49">changeFontsize</span><span style="color:#cccccc">(</span>state<span style="color:#cccccc">.</span>color<span style="color:#cccccc">)</span>
<span style="color:#cccccc">}</span>
<span style="color:#999999">//前进状态的方法</span>
stateControll<span style="color:#cccccc">.</span>prototype<span style="color:#cccccc">.</span><span style="color:#f08d49">saveGo</span> <span style="color:#67cdcc">=</span> <span style="color:#cc99cd">function</span><span style="color:#cccccc">(</span><span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span><span style="color:#cccccc">}</span>window<span style="color:#cccccc">.</span>Editor <span style="color:#67cdcc">=</span> Editor
</code></span></span></span>
建造者模式是把它的模块抽离出独立的类,然后在组合起来
vue 初始化
需求:vue 内部众多模块,而且过程复杂,vue 类也可以看做是一个建造者模式
<span style="background-color:#282c34"><span style="color:#2c3e50"><span style="color:#cccccc"><code><span style="color:#cc99cd">function</span> <span style="color:#f08d49">Vue</span><span style="color:#cccccc">(</span>options<span style="color:#cccccc">)</span><span style="color:#cccccc">{</span><span style="color:#999999">// 只允许用户用new操作符,如果直接调用就抛出警告</span><span style="color:#cc99cd">if</span><span style="color:#cccccc">(</span><span style="color:#67cdcc">!</span><span style="color:#cccccc">(</span><span style="color:#cc99cd">this</span> <span style="color:#cc99cd">instanceof</span> <span style="color:#f8c555">Vue</span><span style="color:#cccccc">)</span><span style="color:#cccccc">)</span><span style="color:#cccccc">{</span>console<span style="color:#cccccc">.</span><span style="color:#f08d49">warn</span><span style="color:#cccccc">(</span><span style="color:#7ec699">'Vue is a constructor and should be called with the `new` keyword'</span><span style="color:#cccccc">)</span><span style="color:#cccccc">}</span><span style="color:#999999">// 初始化配置项</span><span style="color:#cc99cd">this</span><span style="color:#cccccc">.</span><span style="color:#f08d49">_init</span><span style="color:#cccccc">(</span>options<span style="color:#cccccc">)</span>
<span style="color:#cccccc">}</span>initMixin(Vue<span style="color:#cccccc">)</span> <span style="color:#999999">// 初始化系统混入到Vue中去</span>
<span style="color:#f08d49">stateMixin</span><span style="color:#cccccc">(</span>Vue<span style="color:#cccccc">)</span> <span style="color:#999999">// 状态系统混入到Vue中去</span>
<span style="color:#f08d49">eventsMixin</span><span style="color:#cccccc">(</span>Vue<span style="color:#cccccc">)</span> <span style="color:#999999">// 事件系统的混入</span>
<span style="color:#f08d49">lifecycleMixin</span><span style="color:#cccccc">(</span>Vue<span style="color:#cccccc">)</span> <span style="color:#999999">// 生命周期混入</span>
<span style="color:#f08d49">renderMixin</span><span style="color:#cccccc">(</span>Vue<span style="color:#cccccc">)</span> <span style="color:#999999">// 渲染混入</span></code></span></span></span>
通过这些方法和我们上一个案例把模块独立成一个类,把这些类放到暴露出的类里面是一个道理; 只不过这里改成方法,vue 中所有的功能都是独立开发,通过这一系列的混入将其混入进去
# 单例模式的示例
写一个数据存储对象
需求:项目中有一个全局的数据存储者,这个存储者只能有一个 ,不然会需要进行同步,增加复杂度
<span style="background-color:#282c34"><span style="color:#2c3e50"><span style="color:#cccccc"><code><span style="color:#cc99cd">function</span> <span style="color:#f08d49">store</span><span style="color:#cccccc">(</span><span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span><span style="color:#cc99cd">this</span><span style="color:#cccccc">.</span>state <span style="color:#67cdcc">=</span> <span style="color:#cccccc">{</span><span style="color:#cccccc">}</span><span style="color:#cc99cd">if</span> <span style="color:#cccccc">(</span>store<span style="color:#cccccc">.</span>install<span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span><span style="color:#cc99cd">return</span> store<span style="color:#cccccc">.</span>install<span style="color:#cccccc">}</span>store<span style="color:#cccccc">.</span>install <span style="color:#67cdcc">=</span> <span style="color:#cc99cd">this</span>
<span style="color:#cccccc">}</span>store<span style="color:#cccccc">.</span>install <span style="color:#67cdcc">=</span> <span style="color:#cc99cd">null</span>
<span style="color:#cc99cd">var</span> s1 <span style="color:#67cdcc">=</span> <span style="color:#cc99cd">new</span> <span style="color:#f8c555">store</span><span style="color:#cccccc">(</span><span style="color:#cccccc">)</span>
<span style="color:#cc99cd">var</span> s2 <span style="color:#67cdcc">=</span> <span style="color:#cc99cd">new</span> <span style="color:#f8c555">store</span><span style="color:#cccccc">(</span><span style="color:#cccccc">)</span>
s1<span style="color:#cccccc">.</span>state<span style="color:#cccccc">.</span>a <span style="color:#67cdcc">=</span> <span style="color:#f08d49">1</span>
console<span style="color:#cccccc">.</span><span style="color:#f08d49">log</span><span style="color:#cccccc">(</span>s1<span style="color:#cccccc">,</span> s2<span style="color:#cccccc">)</span> <span style="color:#999999">// store { state: { a: 1 } } store { state: { a: 1 } }</span>
</code></span></span></span>
vue-router
需求:vue-router 必须 保障全局有且只有一个,否则的话会错乱
<span style="background-color:#282c34"><span style="color:#2c3e50"><span style="color:#cccccc"><code><span style="color:#cc99cd">let</span> _Vue
<span style="color:#cc99cd">function</span> <span style="color:#f08d49">install</span><span style="color:#cccccc">(</span>Vue<span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span><span style="color:#cc99cd">if</span> <span style="color:#cccccc">(</span>install<span style="color:#cccccc">.</span>installed <span style="color:#67cdcc">&&</span> _Vue <span style="color:#67cdcc">===</span> vue<span style="color:#cccccc">)</span> <span style="color:#cc99cd">return</span>install<span style="color:#cccccc">.</span>installed <span style="color:#67cdcc">=</span> <span style="color:#f08d49">true</span>_Vue <span style="color:#67cdcc">=</span> vue
<span style="color:#cccccc">}</span>
</code></span></span></span>
#2.4 总结
工厂模式:如果你写的模块,需要大量创建类似的对象
建造者模式:需要创建一个需要大量参数,且内部模块庞大
单例模式:防止重复注册,防止有多个对象互相干扰
#3 .提高复用性
什么是好的复用?
- 对象可以再重复使用,不用修改
- 重复代码少
- 模块功能单一
#3.1 提高复用性的设计模式
减少代码数量,高效复用代码
-
桥接模式
目的:通过桥接代替耦合
应用场景:减少模块之间的耦合
-
享元模式
目的:减少对象/代码数量
应用场景:当代码中创建了大量类似对象和类似的代码块
创建高可复用性的代码
-
模版方法模式
目的:定义一系列操作的骨架,简化后面类似操作的内容
应用场景:当项目中出现很多类似操作内容
#3.2 基本结构
桥接模式
<span style="background-color:#282c34"><span style="color:#2c3e50"><span style="color:#cccccc"><code><span style="color:#999999">// 有三种形状,每种形状都有3种颜色</span>
<span style="color:#cc99cd">function</span> <span style="color:#f08d49">rect</span><span style="color:#cccccc">(</span>color<span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span><span style="color:#999999">//矩形</span><span style="color:#f08d49">showcolor</span><span style="color:#cccccc">(</span>color<span style="color:#cccccc">)</span>
<span style="color:#cccccc">}</span>
<span style="color:#cc99cd">function</span> <span style="color:#f08d49">circle</span><span style="color:#cccccc">(</span><span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span><span style="color:#999999">// 圆形</span><span style="color:#f08d49">showcolor</span><span style="color:#cccccc">(</span>clor<span style="color:#cccccc">)</span>
<span style="color:#cccccc">}</span>
<span style="color:#cc99cd">function</span> <span style="color:#f08d49">delta</span><span style="color:#cccccc">(</span>color<span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span><span style="color:#999999">// 三角形</span><span style="color:#f08d49">showcolor</span><span style="color:#cccccc">(</span>clor<span style="color:#cccccc">)</span>
<span style="color:#cccccc">}</span><span style="color:#cc99cd">new</span> <span style="color:#f8c555">circle</span><span style="color:#cccccc">(</span><span style="color:#7ec699">'red'</span><span style="color:#cccccc">)</span>
</code></span></span></span>
- 对于 3 种形状、每种形状有 3 种颜色的需求,可以不用创建 9 种不同颜色的不同形状
- 这个模式把重复的方法抽取出来,然后在桥接出去
这个模式跟我们的建造者模式很类似拆分再组合,建造者模式的核心是如何去构造对象;而我们桥接模式是如何简化我们的代码,提高我们的可复用性,一个关注的是功能一个关注的是创建,这是它们的区别。
享元模式
<span style="background-color:#282c34"><span style="color:#2c3e50"><span style="color:#cccccc"><code> <span style="color:#999999">// 有一百种不同文字的弹窗,每种弹窗行为相同,但是文字和样式不同,我们没必要新间一百个弹窗对象</span><span style="color:#cc99cd">function</span> <span style="color:#f08d49">Pop</span><span style="color:#cccccc">(</span><span style="color:#cccccc">)</span><span style="color:#cccccc">{</span><span style="color:#cccccc">}</span><span style="color:#999999">// 保留同样的行为</span><span style="color:#f8c555">Pop</span><span style="color:#cccccc">.</span>prototype<span style="color:#cccccc">.</span><span style="color:#f08d49">action</span><span style="color:#67cdcc">=</span><span style="color:#cc99cd">function</span><span style="color:#cccccc">(</span><span style="color:#cccccc">)</span><span style="color:#cccccc">{</span><span style="color:#cccccc">}</span><span style="color:#999999">//显示</span><span style="color:#f8c555">Pop</span><span style="color:#cccccc">.</span>prototype<span style="color:#cccccc">.</span><span style="color:#f08d49">show</span><span style="color:#67cdcc">=</span><span style="color:#cc99cd">function</span><span style="color:#cccccc">(</span><span style="color:#cccccc">)</span><span style="color:#cccccc">{</span><span style="color:#cccccc">}</span><span style="color:#999999">// 提取出每个弹窗不同的部分作为一个外部数组</span><span style="color:#cc99cd">var</span> popArr<span style="color:#67cdcc">=</span><span style="color:#cccccc">[</span><span style="color:#cccccc">{</span>text<span style="color:#67cdcc">:</span><span style="color:#7ec699">"window1"</span><span style="color:#cccccc">,</span>style<span style="color:#67cdcc">:</span><span style="color:#cccccc">[</span><span style="color:#f08d49">400</span><span style="color:#cccccc">,</span><span style="color:#f08d49">400</span><span style="color:#cccccc">]</span><span style="color:#cccccc">}</span><span style="color:#cccccc">{</span>text<span style="color:#67cdcc">:</span><span style="color:#7ec699">"window2"</span><span style="color:#cccccc">,</span>style<span style="color:#67cdcc">:</span><span style="color:#cccccc">[</span><span style="color:#f08d49">400</span><span style="color:#cccccc">,</span><span style="color:#f08d49">200</span><span style="color:#cccccc">]</span><span style="color:#cccccc">}</span><span style="color:#cccccc">]</span><span style="color:#cc99cd">var</span> poper<span style="color:#67cdcc">=</span><span style="color:#cc99cd">new</span> <span style="color:#f8c555">Pop</span><span style="color:#cccccc">(</span><span style="color:#cccccc">)</span><span style="color:#cc99cd">for</span><span style="color:#cccccc">(</span><span style="color:#cc99cd">var</span> i<span style="color:#67cdcc">=</span><span style="color:#f08d49">0</span><span style="color:#cccccc">;</span>i<span style="color:#67cdcc"><</span><span style="color:#f08d49">100</span><span style="color:#cccccc">;</span>i<span style="color:#67cdcc">++</span><span style="color:#cccccc">)</span><span style="color:#cccccc">{</span>poper<span style="color:#cccccc">.</span><span style="color:#f08d49">show</span><span style="color:#cccccc">(</span>popArr<span style="color:#cccccc">[</span>i<span style="color:#cccccc">]</span><span style="color:#cccccc">)</span><span style="color:#cccccc">}</span>
</code></span></span></span>
- 只需一个类,不需要 new 一百次弹窗
- 这个类只保留所有弹窗共有的,每个弹窗不同的部分留作为一个公共享元
#模版方法模式
<span style="background-color:#282c34"><span style="color:#2c3e50"><span style="color:#cccccc"><code><span style="color:#999999">// 编写导航组件,有的带消息提示,有的竖着,有的横者</span>
<span style="color:#cc99cd">function</span> <span style="color:#f08d49">baseNav</span><span style="color:#cccccc">(</span><span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span><span style="color:#999999">// 基础类,此处定下基本骨架</span>
<span style="color:#cccccc">}</span>baseNav<span style="color:#cccccc">.</span>prototype<span style="color:#cccccc">.</span><span style="color:#f08d49">action</span> <span style="color:#67cdcc">=</span> <span style="color:#cc99cd">function</span><span style="color:#cccccc">(</span>fn<span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span><span style="color:#999999">// 特异性的处理,留一个回调等待具体实现</span>
<span style="color:#cccccc">}</span>
</code></span></span></span>
- 导航组件多种多样,可能后面还会新增类型,那么我们不妨写一个基础的组件库,然后具体的实现,延迟到具体的使用时
#3.3 应用示例
# 桥接模式的示例
创建不同的选中效果
需求:有一组菜单,上面每种选项都有不同的选中效果
<span style="background-color:#282c34"><span style="color:#2c3e50"><span style="color:#cccccc"><code><span style="color:#999999">// 一般做法</span>
<span style="color:#999999">//menu1,menu2,menu3</span>
<span style="color:#cc99cd">function</span> <span style="color:#f08d49">menuItem</span><span style="color:#cccccc">(</span>word<span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span><span style="color:#cc99cd">this</span><span style="color:#cccccc">.</span>word <span style="color:#67cdcc">=</span> <span style="color:#7ec699">''</span><span style="color:#cc99cd">this</span><span style="color:#cccccc">.</span>dom <span style="color:#67cdcc">=</span> document<span style="color:#cccccc">.</span><span style="color:#f08d49">createElement</span><span style="color:#cccccc">(</span><span style="color:#7ec699">'div'</span><span style="color:#cccccc">)</span><span style="color:#cc99cd">this</span><span style="color:#cccccc">.</span>dom<span style="color:#cccccc">.</span>innerHTML <span style="color:#67cdcc">=</span> <span style="color:#cc99cd">this</span><span style="color:#cccccc">.</span>word
<span style="color:#cccccc">}</span>
<span style="color:#cc99cd">var</span> menu1 <span style="color:#67cdcc">=</span> <span style="color:#cc99cd">new</span> <span style="color:#f8c555">menuItem</span><span style="color:#cccccc">(</span><span style="color:#7ec699">'menu1'</span><span style="color:#cccccc">)</span>
<span style="color:#cc99cd">var</span> menu2 <span style="color:#67cdcc">=</span> <span style="color:#cc99cd">new</span> <span style="color:#f8c555">menuItem</span><span style="color:#cccccc">(</span><span style="color:#7ec699">'menu2'</span><span style="color:#cccccc">)</span>
<span style="color:#cc99cd">var</span> menu3 <span style="color:#67cdcc">=</span> <span style="color:#cc99cd">new</span> <span style="color:#f8c555">menuItem</span><span style="color:#cccccc">(</span><span style="color:#7ec699">'menu3'</span><span style="color:#cccccc">)</span>
menu1<span style="color:#cccccc">.</span><span style="color:#f08d49">onmouseover</span> <span style="color:#67cdcc">=</span> <span style="color:#cc99cd">function</span><span style="color:#cccccc">(</span><span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span>menu1<span style="color:#cccccc">.</span>style<span style="color:#cccccc">.</span>color <span style="color:#67cdcc">=</span> <span style="color:#7ec699">'red'</span>
<span style="color:#cccccc">}</span>
menu2<span style="color:#cccccc">.</span><span style="color:#f08d49">onmouseover</span> <span style="color:#67cdcc">=</span> <span style="color:#cc99cd">function</span><span style="color:#cccccc">(</span><span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span>menu1<span style="color:#cccccc">.</span>style<span style="color:#cccccc">.</span>color <span style="color:#67cdcc">=</span> <span style="color:#7ec699">'green'</span>
<span style="color:#cccccc">}</span>
menu3<span style="color:#cccccc">.</span><span style="color:#f08d49">onmouseover</span> <span style="color:#67cdcc">=</span> <span style="color:#cc99cd">function</span><span style="color:#cccccc">(</span><span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span>menu1<span style="color:#cccccc">.</span>style<span style="color:#cccccc">.</span>color <span style="color:#67cdcc">=</span> <span style="color:#7ec699">'blue'</span>
<span style="color:#cccccc">}</span>
menu1<span style="color:#cccccc">.</span><span style="color:#f08d49">onmouseout</span> <span style="color:#67cdcc">=</span> <span style="color:#cc99cd">function</span><span style="color:#cccccc">(</span><span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span>menu1<span style="color:#cccccc">.</span>style<span style="color:#cccccc">.</span>color <span style="color:#67cdcc">=</span> <span style="color:#7ec699">'white'</span>
<span style="color:#cccccc">}</span>
menu2<span style="color:#cccccc">.</span><span style="color:#f08d49">onmouseout</span> <span style="color:#67cdcc">=</span> <span style="color:#cc99cd">function</span><span style="color:#cccccc">(</span><span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span>menu1<span style="color:#cccccc">.</span>style<span style="color:#cccccc">.</span>color <span style="color:#67cdcc">=</span> <span style="color:#7ec699">'white'</span>
<span style="color:#cccccc">}</span>
menu3<span style="color:#cccccc">.</span><span style="color:#f08d49">onmouseout</span> <span style="color:#67cdcc">=</span> <span style="color:#cc99cd">function</span><span style="color:#cccccc">(</span><span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span>menu1<span style="color:#cccccc">.</span>style<span style="color:#cccccc">.</span>color <span style="color:#67cdcc">=</span> <span style="color:#7ec699">'white'</span>
<span style="color:#cccccc">}</span><span style="color:#999999">// 桥接模式做法</span>
<span style="color:#cc99cd">function</span> <span style="color:#f08d49">menuItem</span><span style="color:#cccccc">(</span>word<span style="color:#cccccc">,</span> color<span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span><span style="color:#cc99cd">this</span><span style="color:#cccccc">.</span>word <span style="color:#67cdcc">=</span> word<span style="color:#cc99cd">this</span><span style="color:#cccccc">.</span>color <span style="color:#67cdcc">=</span> color<span style="color:#cc99cd">this</span><span style="color:#cccccc">.</span>dom <span style="color:#67cdcc">=</span> document<span style="color:#cccccc">.</span><span style="color:#f08d49">createElement</span><span style="color:#cccccc">(</span><span style="color:#7ec699">'div'</span><span style="color:#cccccc">)</span><span style="color:#cc99cd">this</span><span style="color:#cccccc">.</span>dom<span style="color:#cccccc">.</span>innerHTML <span style="color:#67cdcc">=</span> <span style="color:#cc99cd">this</span><span style="color:#cccccc">.</span>worddocument<span style="color:#cccccc">.</span><span style="color:#f08d49">getElementById</span><span style="color:#cccccc">(</span><span style="color:#7ec699">'app'</span><span style="color:#cccccc">)</span><span style="color:#cccccc">.</span><span style="color:#f08d49">appendChild</span><span style="color:#cccccc">(</span><span style="color:#cc99cd">this</span><span style="color:#cccccc">.</span>dom<span style="color:#cccccc">)</span>
<span style="color:#cccccc">}</span>menuItem<span style="color:#cccccc">.</span>prototype<span style="color:#cccccc">.</span><span style="color:#f08d49">bind</span> <span style="color:#67cdcc">=</span> <span style="color:#cc99cd">function</span><span style="color:#cccccc">(</span><span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span><span style="color:#cc99cd">var</span> self <span style="color:#67cdcc">=</span> <span style="color:#cc99cd">this</span><span style="color:#cc99cd">this</span><span style="color:#cccccc">.</span>dom<span style="color:#cccccc">.</span><span style="color:#f08d49">onmouseover</span> <span style="color:#67cdcc">=</span> <span style="color:#cc99cd">function</span><span style="color:#cccccc">(</span><span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span>console<span style="color:#cccccc">.</span><span style="color:#f08d49">log</span><span style="color:#cccccc">(</span>self<span style="color:#cccccc">.</span>color<span style="color:#cccccc">)</span><span style="color:#cc99cd">this</span><span style="color:#cccccc">.</span>style<span style="color:#cccccc">.</span>color <span style="color:#67cdcc">=</span> self<span style="color:#cccccc">.</span>color<span style="color:#cccccc">.</span>colorOver<span style="color:#cccccc">}</span><span style="color:#cc99cd">this</span><span style="color:#cccccc">.</span>dom<span style="color:#cccccc">.</span><span style="color:#f08d49">onmouseout</span> <span style="color:#67cdcc">=</span> <span style="color:#cc99cd">function</span><span style="color:#cccccc">(</span><span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span><span style="color:#cc99cd">this</span><span style="color:#cccccc">.</span>style<span style="color:#cccccc">.</span>color <span style="color:#67cdcc">=</span> self<span style="color:#cccccc">.</span>color<span style="color:#cccccc">.</span>colorOut<span style="color:#cccccc">}</span>
<span style="color:#cccccc">}</span>
<span style="color:#cc99cd">function</span> <span style="color:#f08d49">menuColor</span><span style="color:#cccccc">(</span>colorover<span style="color:#cccccc">,</span> colorout<span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span><span style="color:#cc99cd">this</span><span style="color:#cccccc">.</span>colorOver <span style="color:#67cdcc">=</span> colorover<span style="color:#cc99cd">this</span><span style="color:#cccccc">.</span>colorOut <span style="color:#67cdcc">=</span> colorout
<span style="color:#cccccc">}</span><span style="color:#cc99cd">var</span> data <span style="color:#67cdcc">=</span> <span style="color:#cccccc">[</span><span style="color:#cccccc">{</span> word<span style="color:#67cdcc">:</span> <span style="color:#7ec699">'menu1'</span><span style="color:#cccccc">,</span> color<span style="color:#67cdcc">:</span> <span style="color:#cccccc">[</span><span style="color:#7ec699">'red'</span><span style="color:#cccccc">,</span> <span style="color:#7ec699">'black'</span><span style="color:#cccccc">]</span> <span style="color:#cccccc">}</span><span style="color:#cccccc">,</span><span style="color:#cccccc">{</span> word<span style="color:#67cdcc">:</span> <span style="color:#7ec699">'menu2'</span><span style="color:#cccccc">,</span> color<span style="color:#67cdcc">:</span> <span style="color:#cccccc">[</span><span style="color:#7ec699">'green'</span><span style="color:#cccccc">,</span> <span style="color:#7ec699">'black'</span><span style="color:#cccccc">]</span> <span style="color:#cccccc">}</span><span style="color:#cccccc">,</span><span style="color:#cccccc">{</span> word<span style="color:#67cdcc">:</span> <span style="color:#7ec699">'menu3'</span><span style="color:#cccccc">,</span> color<span style="color:#67cdcc">:</span> <span style="color:#cccccc">[</span><span style="color:#7ec699">'blue'</span><span style="color:#cccccc">,</span> <span style="color:#7ec699">'black'</span><span style="color:#cccccc">]</span> <span style="color:#cccccc">}</span>
<span style="color:#cccccc">]</span>
<span style="color:#cc99cd">for</span> <span style="color:#cccccc">(</span><span style="color:#cc99cd">var</span> i <span style="color:#67cdcc">=</span> <span style="color:#f08d49">0</span><span style="color:#cccccc">;</span> i <span style="color:#67cdcc"><</span> data<span style="color:#cccccc">.</span>length<span style="color:#cccccc">;</span> i<span style="color:#67cdcc">++</span><span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span><span style="color:#cc99cd">new</span> <span style="color:#f8c555">menuItem</span><span style="color:#cccccc">(</span>data<span style="color:#cccccc">[</span>i<span style="color:#cccccc">]</span><span style="color:#cccccc">.</span>word<span style="color:#cccccc">,</span><span style="color:#cc99cd">new</span> <span style="color:#f8c555">menuColor</span><span style="color:#cccccc">(</span>data<span style="color:#cccccc">[</span>i<span style="color:#cccccc">]</span><span style="color:#cccccc">.</span>color<span style="color:#cccccc">[</span><span style="color:#f08d49">0</span><span style="color:#cccccc">]</span><span style="color:#cccccc">,</span> data<span style="color:#cccccc">[</span>i<span style="color:#cccccc">]</span><span style="color:#cccccc">.</span>color<span style="color:#cccccc">[</span><span style="color:#f08d49">1</span><span style="color:#cccccc">]</span><span style="color:#cccccc">)</span><span style="color:#cccccc">)</span><span style="color:#cccccc">.</span><span style="color:#f08d49">bind</span><span style="color:#cccccc">(</span><span style="color:#cccccc">)</span>
<span style="color:#cccccc">}</span>
</code></span></span></span>
Express 中创建 get 等方法
需求:express 中 get,post 等方法,有七八个,如何快速地创建。
<span style="background-color:#282c34"><span style="color:#2c3e50"><span style="color:#cccccc"><code><span style="color:#cc99cd">var</span> methods <span style="color:#67cdcc">=</span> <span style="color:#cccccc">[</span><span style="color:#7ec699">'get'</span><span style="color:#cccccc">,</span> <span style="color:#7ec699">'post'</span><span style="color:#cccccc">,</span> <span style="color:#7ec699">'delete'</span><span style="color:#cccccc">,</span> <span style="color:#7ec699">'put'</span><span style="color:#cccccc">]</span>
methods<span style="color:#cccccc">.</span><span style="color:#f08d49">forEach</span><span style="color:#cccccc">(</span><span style="color:#cc99cd">function</span><span style="color:#cccccc">(</span>method<span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span>app<span style="color:#cccccc">[</span>method<span style="color:#cccccc">]</span> <span style="color:#67cdcc">=</span> <span style="color:#cc99cd">function</span><span style="color:#cccccc">(</span><span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span><span style="color:#999999">//利用桥接过来的route来完成post,get等请求</span>route<span style="color:#cccccc">[</span>method<span style="color:#cccccc">]</span><span style="color:#cccccc">.</span><span style="color:#f08d49">apply</span><span style="color:#cccccc">(</span>route<span style="color:#cccccc">,</span> <span style="color:#f08d49">slice</span><span style="color:#cccccc">.</span><span style="color:#f08d49">call</span><span style="color:#cccccc">(</span>arguments<span style="color:#cccccc">,</span> <span style="color:#f08d49">1</span><span style="color:#cccccc">)</span><span style="color:#cccccc">)</span><span style="color:#cccccc">}</span>
<span style="color:#cccccc">}</span><span style="color:#cccccc">)</span>
</code></span></span></span>
#享元模式的示例
文件上传
需求:项目中有一个文件上传功能,该功能可以上传多个文件
一般做法
<span style="background-color:#282c34"><span style="color:#2c3e50"><span style="color:#cccccc"><code><span style="color:#999999">//文件上传</span>
<span style="color:#cc99cd">function</span> <span style="color:#f08d49">uploader</span><span style="color:#cccccc">(</span>fileType<span style="color:#cccccc">,</span> file<span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span><span style="color:#cc99cd">this</span><span style="color:#cccccc">.</span>fileType <span style="color:#67cdcc">=</span> fileType<span style="color:#cc99cd">this</span><span style="color:#cccccc">.</span>file <span style="color:#67cdcc">=</span> file
<span style="color:#cccccc">}</span>
uploader<span style="color:#cccccc">.</span>prototype<span style="color:#cccccc">.</span><span style="color:#f08d49">init</span> <span style="color:#67cdcc">=</span> <span style="color:#cc99cd">function</span><span style="color:#cccccc">(</span><span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span><span style="color:#999999">//初始化文件上传的html</span>
<span style="color:#cccccc">}</span>
uploader<span style="color:#cccccc">.</span>prototype<span style="color:#cccccc">.</span><span style="color:#f08d49">delete</span> <span style="color:#67cdcc">=</span> <span style="color:#cc99cd">function</span><span style="color:#cccccc">(</span><span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span><span style="color:#999999">//删除掉该html</span>
<span style="color:#cccccc">}</span>
uploader<span style="color:#cccccc">.</span>prototype<span style="color:#cccccc">.</span><span style="color:#f08d49">uploading</span> <span style="color:#67cdcc">=</span> <span style="color:#cc99cd">function</span><span style="color:#cccccc">(</span><span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span><span style="color:#999999">//上传</span>
<span style="color:#cccccc">}</span><span style="color:#cc99cd">new</span> <span style="color:#f8c555">uploader</span><span style="color:#cccccc">(</span><span style="color:#7ec699">'img'</span><span style="color:#cccccc">,</span> fileob1<span style="color:#cccccc">)</span>
<span style="color:#cc99cd">new</span> <span style="color:#f8c555">uploader</span><span style="color:#cccccc">(</span><span style="color:#7ec699">'txt'</span><span style="color:#cccccc">,</span> fileob2<span style="color:#cccccc">)</span>
<span style="color:#cc99cd">new</span> <span style="color:#f8c555">uploader</span><span style="color:#cccccc">(</span><span style="color:#7ec699">'img'</span><span style="color:#cccccc">,</span> fileob3<span style="color:#cccccc">)</span>
<span style="color:#cc99cd">new</span> <span style="color:#f8c555">uploader</span><span style="color:#cccccc">(</span><span style="color:#7ec699">'word'</span><span style="color:#cccccc">,</span> fileob4<span style="color:#cccccc">)</span>
</code></span></span></span>
享元模式
<span style="background-color:#282c34"><span style="color:#2c3e50"><span style="color:#cccccc"><code><span style="color:#999999">//fileType,file</span>
<span style="color:#cc99cd">function</span> <span style="color:#f08d49">uploader</span><span style="color:#cccccc">(</span><span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span><span style="color:#cccccc">}</span>
uploader<span style="color:#cccccc">.</span>prototype<span style="color:#cccccc">.</span><span style="color:#f08d49">init</span> <span style="color:#67cdcc">=</span> <span style="color:#cc99cd">function</span><span style="color:#cccccc">(</span><span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span><span style="color:#999999">//初始化文件上传的html</span>
<span style="color:#cccccc">}</span>
uploader<span style="color:#cccccc">.</span>prototype<span style="color:#cccccc">.</span><span style="color:#f08d49">delete</span> <span style="color:#67cdcc">=</span> <span style="color:#cc99cd">function</span><span style="color:#cccccc">(</span><span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span><span style="color:#999999">//删除掉该html</span>
<span style="color:#cccccc">}</span>
uploader<span style="color:#cccccc">.</span>prototype<span style="color:#cccccc">.</span><span style="color:#f08d49">uploading</span> <span style="color:#67cdcc">=</span> <span style="color:#cc99cd">function</span><span style="color:#cccccc">(</span>filetype<span style="color:#cccccc">,</span> file<span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span><span style="color:#cccccc">}</span><span style="color:#cc99cd">var</span> fileob1<span style="color:#cccccc">,</span> fileob2<span style="color:#cccccc">,</span> fileob3<span style="color:#cccccc">,</span> fileob4
<span style="color:#cc99cd">var</span> data <span style="color:#67cdcc">=</span> <span style="color:#cccccc">[</span><span style="color:#cccccc">{</span>type<span style="color:#67cdcc">:</span> <span style="color:#7ec699">'img'</span><span style="color:#cccccc">,</span>file<span style="color:#67cdcc">:</span> fileob1<span style="color:#cccccc">}</span><span style="color:#cccccc">,</span><span style="color:#cccccc">{</span>type<span style="color:#67cdcc">:</span> <span style="color:#7ec699">'txt'</span><span style="color:#cccccc">,</span>file<span style="color:#67cdcc">:</span> fileob2<span style="color:#cccccc">}</span><span style="color:#cccccc">,</span><span style="color:#cccccc">{</span>type<span style="color:#67cdcc">:</span> <span style="color:#7ec699">'img'</span><span style="color:#cccccc">,</span>file<span style="color:#67cdcc">:</span> fileob3<span style="color:#cccccc">}</span><span style="color:#cccccc">,</span><span style="color:#cccccc">{</span>type<span style="color:#67cdcc">:</span> <span style="color:#7ec699">'word'</span><span style="color:#cccccc">,</span>file<span style="color:#67cdcc">:</span> fileob4<span style="color:#cccccc">}</span>
<span style="color:#cccccc">]</span>
<span style="color:#cc99cd">var</span> uploader <span style="color:#67cdcc">=</span> <span style="color:#cc99cd">new</span> <span style="color:#f8c555">uploader</span><span style="color:#cccccc">(</span><span style="color:#cccccc">)</span>
<span style="color:#cc99cd">for</span> <span style="color:#cccccc">(</span><span style="color:#cc99cd">var</span> i <span style="color:#67cdcc">=</span> <span style="color:#f08d49">0</span><span style="color:#cccccc">;</span> i <span style="color:#67cdcc"><</span> data<span style="color:#cccccc">.</span>length<span style="color:#cccccc">;</span> i<span style="color:#67cdcc">++</span><span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span>uploader<span style="color:#cccccc">.</span><span style="color:#f08d49">uploading</span><span style="color:#cccccc">(</span>data<span style="color:#cccccc">[</span>i<span style="color:#cccccc">]</span><span style="color:#cccccc">.</span>type<span style="color:#cccccc">,</span> data<span style="color:#cccccc">[</span>i<span style="color:#cccccc">]</span><span style="color:#cccccc">.</span>file<span style="color:#cccccc">)</span>
<span style="color:#cccccc">}</span>
</code></span></span></span>
jQuery 的 extend
需求:extends 方法,需要判断参数数量来进行不同的操作
<span style="background-color:#282c34"><span style="color:#2c3e50"><span style="color:#cccccc"><code><span style="color:#999999">// 一般做法</span>
<span style="color:#cc99cd">var</span> jQuery <span style="color:#67cdcc">=</span> <span style="color:#cccccc">{</span><span style="color:#cccccc">}</span>
jQuery<span style="color:#cccccc">.</span>fn <span style="color:#67cdcc">=</span> <span style="color:#cccccc">{</span><span style="color:#cccccc">}</span>
jQuery<span style="color:#cccccc">.</span>extend <span style="color:#67cdcc">=</span> jQuery<span style="color:#cccccc">.</span>fn<span style="color:#cccccc">.</span><span style="color:#f08d49">extend</span> <span style="color:#67cdcc">=</span> <span style="color:#cc99cd">function</span><span style="color:#cccccc">(</span><span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span><span style="color:#cc99cd">if</span> <span style="color:#cccccc">(</span>arguments<span style="color:#cccccc">.</span>length <span style="color:#67cdcc">==</span> <span style="color:#f08d49">1</span><span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span><span style="color:#cc99cd">for</span> <span style="color:#cccccc">(</span><span style="color:#cc99cd">var</span> item <span style="color:#cc99cd">in</span> arguments<span style="color:#cccccc">[</span><span style="color:#f08d49">0</span><span style="color:#cccccc">]</span><span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span><span style="color:#cc99cd">this</span><span style="color:#cccccc">[</span>item<span style="color:#cccccc">]</span> <span style="color:#67cdcc">=</span> arguments<span style="color:#cccccc">[</span><span style="color:#f08d49">0</span><span style="color:#cccccc">]</span><span style="color:#cccccc">[</span>item<span style="color:#cccccc">]</span><span style="color:#cccccc">}</span><span style="color:#cccccc">}</span> <span style="color:#cc99cd">else</span> <span style="color:#cc99cd">if</span> <span style="color:#cccccc">(</span>arguments<span style="color:#cccccc">.</span>length <span style="color:#67cdcc">==</span> <span style="color:#f08d49">2</span><span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span><span style="color:#cc99cd">for</span> <span style="color:#cccccc">(</span><span style="color:#cc99cd">var</span> item <span style="color:#cc99cd">in</span> arguments<span style="color:#cccccc">[</span><span style="color:#f08d49">1</span><span style="color:#cccccc">]</span><span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span>arguments<span style="color:#cccccc">[</span><span style="color:#f08d49">0</span><span style="color:#cccccc">]</span><span style="color:#cccccc">[</span>item<span style="color:#cccccc">]</span> <span style="color:#67cdcc">=</span> arguments<span style="color:#cccccc">[</span><span style="color:#f08d49">1</span><span style="color:#cccccc">]</span><span style="color:#cccccc">[</span>item<span style="color:#cccccc">]</span><span style="color:#cccccc">}</span><span style="color:#cc99cd">return</span> arguments<span style="color:#cccccc">[</span><span style="color:#f08d49">0</span><span style="color:#cccccc">]</span><span style="color:#cccccc">}</span>
<span style="color:#cccccc">}</span><span style="color:#999999">// 享元做法,保留一个公共的for循环</span>
jQuery<span style="color:#cccccc">.</span>extend <span style="color:#67cdcc">=</span> jQuery<span style="color:#cccccc">.</span>fn<span style="color:#cccccc">.</span><span style="color:#f08d49">extend</span> <span style="color:#67cdcc">=</span> <span style="color:#cc99cd">function</span><span style="color:#cccccc">(</span><span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span><span style="color:#cc99cd">var</span> target <span style="color:#67cdcc">=</span> arguments<span style="color:#cccccc">[</span><span style="color:#f08d49">0</span><span style="color:#cccccc">]</span><span style="color:#cc99cd">var</span> source<span style="color:#cc99cd">if</span> <span style="color:#cccccc">(</span>arguments<span style="color:#cccccc">.</span>length <span style="color:#67cdcc">==</span> <span style="color:#f08d49">1</span><span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span>target <span style="color:#67cdcc">=</span> <span style="color:#cc99cd">this</span>source <span style="color:#67cdcc">=</span> arguments<span style="color:#cccccc">[</span><span style="color:#f08d49">0</span><span style="color:#cccccc">]</span><span style="color:#cccccc">}</span> <span style="color:#cc99cd">else</span> <span style="color:#cc99cd">if</span> <span style="color:#cccccc">(</span>arguments<span style="color:#cccccc">.</span>length <span style="color:#67cdcc">==</span> <span style="color:#f08d49">2</span><span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span>target <span style="color:#67cdcc">=</span> arguments<span style="color:#cccccc">[</span><span style="color:#f08d49">0</span><span style="color:#cccccc">]</span>source <span style="color:#67cdcc">=</span> arguments<span style="color:#cccccc">[</span><span style="color:#f08d49">1</span><span style="color:#cccccc">]</span><span style="color:#cccccc">}</span><span style="color:#cc99cd">for</span> <span style="color:#cccccc">(</span><span style="color:#cc99cd">var</span> item <span style="color:#cc99cd">in</span> source<span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span>target<span style="color:#cccccc">[</span>item<span style="color:#cccccc">]</span> <span style="color:#67cdcc">=</span> source<span style="color:#cccccc">[</span>item<span style="color:#cccccc">]</span><span style="color:#cccccc">}</span><span style="color:#cc99cd">return</span> target
<span style="color:#cccccc">}</span>
</code></span></span></span>
# 模版方法模式的示例
编写一个弹窗组件
需求:项目有一系列弹窗,每个弹窗的行为、大小、文字不同
<span style="background-color:#282c34"><span style="color:#2c3e50"><span style="color:#cccccc"><code><span style="color:#cc99cd">function</span> <span style="color:#f08d49">basePop</span><span style="color:#cccccc">(</span>word<span style="color:#cccccc">,</span> size<span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span><span style="color:#cc99cd">this</span><span style="color:#cccccc">.</span>word <span style="color:#67cdcc">=</span> word<span style="color:#cc99cd">this</span><span style="color:#cccccc">.</span>size <span style="color:#67cdcc">=</span> size<span style="color:#cc99cd">this</span><span style="color:#cccccc">.</span>dom <span style="color:#67cdcc">=</span> <span style="color:#cc99cd">null</span>
<span style="color:#cccccc">}</span>
basePop<span style="color:#cccccc">.</span>prototype<span style="color:#cccccc">.</span><span style="color:#f08d49">init</span> <span style="color:#67cdcc">=</span> <span style="color:#cc99cd">function</span><span style="color:#cccccc">(</span><span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span><span style="color:#cc99cd">var</span> div <span style="color:#67cdcc">=</span> document<span style="color:#cccccc">.</span><span style="color:#f08d49">createElement</span><span style="color:#cccccc">(</span><span style="color:#7ec699">'div'</span><span style="color:#cccccc">)</span>div<span style="color:#cccccc">.</span>innerHTML <span style="color:#67cdcc">=</span> <span style="color:#cc99cd">this</span><span style="color:#cccccc">.</span>worddiv<span style="color:#cccccc">.</span>style<span style="color:#cccccc">.</span>width <span style="color:#67cdcc">=</span> <span style="color:#cc99cd">this</span><span style="color:#cccccc">.</span>size<span style="color:#cccccc">.</span>width <span style="color:#67cdcc">+</span> <span style="color:#7ec699">'px'</span>div<span style="color:#cccccc">.</span>style<span style="color:#cccccc">.</span>height <span style="color:#67cdcc">=</span> <span style="color:#cc99cd">this</span><span style="color:#cccccc">.</span>size<span style="color:#cccccc">.</span>height <span style="color:#67cdcc">+</span> <span style="color:#7ec699">'px'</span><span style="color:#cc99cd">this</span><span style="color:#cccccc">.</span>dom <span style="color:#67cdcc">=</span> div
<span style="color:#cccccc">}</span>
basePop<span style="color:#cccccc">.</span>prototype<span style="color:#cccccc">.</span><span style="color:#f08d49">hidden</span> <span style="color:#67cdcc">=</span> <span style="color:#cc99cd">function</span><span style="color:#cccccc">(</span><span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span><span style="color:#999999">//定义基础操作</span><span style="color:#cc99cd">this</span><span style="color:#cccccc">.</span>dom<span style="color:#cccccc">.</span>style<span style="color:#cccccc">.</span>display <span style="color:#67cdcc">=</span> <span style="color:#7ec699">'none'</span>
<span style="color:#cccccc">}</span>
basePop<span style="color:#cccccc">.</span>prototype<span style="color:#cccccc">.</span><span style="color:#f08d49">confirm</span> <span style="color:#67cdcc">=</span> <span style="color:#cc99cd">function</span><span style="color:#cccccc">(</span><span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span><span style="color:#999999">//定义基础操作</span><span style="color:#cc99cd">this</span><span style="color:#cccccc">.</span>dom<span style="color:#cccccc">.</span>style<span style="color:#cccccc">.</span>display <span style="color:#67cdcc">=</span> <span style="color:#7ec699">'none'</span>
<span style="color:#cccccc">}</span>
<span style="color:#cc99cd">function</span> <span style="color:#f08d49">ajaxPop</span><span style="color:#cccccc">(</span>word<span style="color:#cccccc">,</span> size<span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span><span style="color:#f08d49">basePop</span><span style="color:#cccccc">.</span><span style="color:#f08d49">call</span><span style="color:#cccccc">(</span><span style="color:#cc99cd">this</span><span style="color:#cccccc">,</span> word<span style="color:#cccccc">,</span> size<span style="color:#cccccc">)</span>
<span style="color:#cccccc">}</span>
ajaxPop<span style="color:#cccccc">.</span>prototype <span style="color:#67cdcc">=</span> <span style="color:#cc99cd">new</span> <span style="color:#f8c555">basePop</span><span style="color:#cccccc">(</span><span style="color:#cccccc">)</span>
<span style="color:#cc99cd">var</span> hidden <span style="color:#67cdcc">=</span> ajaxPop<span style="color:#cccccc">.</span>prototype<span style="color:#cccccc">.</span>hidden
ajaxPop<span style="color:#cccccc">.</span>prototype<span style="color:#cccccc">.</span><span style="color:#f08d49">hidden</span> <span style="color:#67cdcc">=</span> <span style="color:#cc99cd">function</span><span style="color:#cccccc">(</span><span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span><span style="color:#f08d49">hidden</span><span style="color:#cccccc">.</span><span style="color:#f08d49">call</span><span style="color:#cccccc">(</span><span style="color:#cc99cd">this</span><span style="color:#cccccc">)</span>console<span style="color:#cccccc">.</span><span style="color:#f08d49">log</span><span style="color:#cccccc">(</span><span style="color:#f08d49">1</span><span style="color:#cccccc">)</span>
<span style="color:#cccccc">}</span>
<span style="color:#cc99cd">var</span> confirm <span style="color:#67cdcc">=</span> ajaxPop<span style="color:#cccccc">.</span>prototype<span style="color:#cccccc">.</span>confirm
ajaxPop<span style="color:#cccccc">.</span>prototype<span style="color:#cccccc">.</span><span style="color:#f08d49">confirm</span> <span style="color:#67cdcc">=</span> <span style="color:#cc99cd">function</span><span style="color:#cccccc">(</span><span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span><span style="color:#f08d49">confirm</span><span style="color:#cccccc">.</span><span style="color:#f08d49">call</span><span style="color:#cccccc">(</span><span style="color:#cc99cd">this</span><span style="color:#cccccc">)</span>console<span style="color:#cccccc">.</span><span style="color:#f08d49">log</span><span style="color:#cccccc">(</span><span style="color:#f08d49">1</span><span style="color:#cccccc">)</span>
<span style="color:#cccccc">}</span>
<span style="color:#cc99cd">var</span> pop <span style="color:#67cdcc">=</span> <span style="color:#cc99cd">new</span> <span style="color:#f8c555">ajaxPop</span><span style="color:#cccccc">(</span><span style="color:#7ec699">'sendmes'</span><span style="color:#cccccc">,</span> <span style="color:#cccccc">{</span> width<span style="color:#67cdcc">:</span> <span style="color:#f08d49">100</span><span style="color:#cccccc">,</span> height<span style="color:#67cdcc">:</span> <span style="color:#f08d49">300</span> <span style="color:#cccccc">}</span><span style="color:#cccccc">)</span>
pop<span style="color:#cccccc">.</span><span style="color:#f08d49">init</span><span style="color:#cccccc">(</span><span style="color:#cccccc">)</span>
pop<span style="color:#cccccc">.</span><span style="color:#f08d49">confirm</span><span style="color:#cccccc">(</span><span style="color:#cccccc">)</span><span style="color:#cc99cd">var</span> axios <span style="color:#67cdcc">=</span> <span style="color:#cccccc">{</span><span style="color:#f08d49">get</span><span style="color:#67cdcc">:</span> <span style="color:#cc99cd">function</span><span style="color:#cccccc">(</span><span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span><span style="color:#cc99cd">return</span> Promise<span style="color:#cccccc">.</span><span style="color:#f08d49">resolve</span><span style="color:#cccccc">(</span><span style="color:#cccccc">)</span><span style="color:#cccccc">}</span>
<span style="color:#cccccc">}</span>
</code></span></span></span>
上面这个就是我们面向对象中的继承,模版模式不一定非要通过继承方式来完成,它强调先定义后面进行不同维度的操作的基本行为;
然后在这个基本行为上有扩展的空间,这就是我们模版方法的目的。
封装一个算法计算器
需求:现在我们有一系列自己的算法,但是这个算法常在不同的地方需要增加一些不同的操作
<span style="background-color:#282c34"><span style="color:#2c3e50"><span style="color:#cccccc"><code><span style="color:#999999">//算法计算器</span><span style="color:#cc99cd">function</span> <span style="color:#f08d49">counter</span><span style="color:#cccccc">(</span><span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span><span style="color:#cc99cd">this</span><span style="color:#cccccc">.</span>beforeCounter <span style="color:#67cdcc">=</span> <span style="color:#cccccc">[</span><span style="color:#cccccc">]</span><span style="color:#cc99cd">this</span><span style="color:#cccccc">.</span>afterCounter <span style="color:#67cdcc">=</span> <span style="color:#cccccc">[</span><span style="color:#cccccc">]</span>
<span style="color:#cccccc">}</span><span style="color:#999999">//然后我们把具体的不同部分留到具体使用的时候去扩展</span>
<span style="color:#999999">//所以我们定义两个方法来扩展</span>
counter<span style="color:#cccccc">.</span>prototype<span style="color:#cccccc">.</span><span style="color:#f08d49">addBefore</span> <span style="color:#67cdcc">=</span> <span style="color:#cc99cd">function</span><span style="color:#cccccc">(</span>fn<span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span><span style="color:#cc99cd">this</span><span style="color:#cccccc">.</span>beforeCounter<span style="color:#cccccc">.</span><span style="color:#f08d49">push</span><span style="color:#cccccc">(</span>fn<span style="color:#cccccc">)</span>
<span style="color:#cccccc">}</span>
counter<span style="color:#cccccc">.</span>prototype<span style="color:#cccccc">.</span><span style="color:#f08d49">addAfter</span> <span style="color:#67cdcc">=</span> <span style="color:#cc99cd">function</span><span style="color:#cccccc">(</span>fn<span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span><span style="color:#cc99cd">this</span><span style="color:#cccccc">.</span>afterCounter<span style="color:#cccccc">.</span><span style="color:#f08d49">push</span><span style="color:#cccccc">(</span>fn<span style="color:#cccccc">)</span>
<span style="color:#cccccc">}</span><span style="color:#999999">//最终计算方法</span>
counter<span style="color:#cccccc">.</span>prototype<span style="color:#cccccc">.</span><span style="color:#f08d49">count</span> <span style="color:#67cdcc">=</span> <span style="color:#cc99cd">function</span><span style="color:#cccccc">(</span>num<span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span><span style="color:#999999">//结果变量</span><span style="color:#cc99cd">var</span> _resultnum <span style="color:#67cdcc">=</span> num<span style="color:#999999">//算法队列数组组装</span><span style="color:#cc99cd">var</span> _arr <span style="color:#67cdcc">=</span> <span style="color:#cccccc">[</span>baseCount<span style="color:#cccccc">]</span>_arr <span style="color:#67cdcc">=</span> <span style="color:#cc99cd">this</span><span style="color:#cccccc">.</span>beforeCounter<span style="color:#cccccc">.</span><span style="color:#f08d49">concat</span><span style="color:#cccccc">(</span>_arr<span style="color:#cccccc">)</span>_arr <span style="color:#67cdcc">=</span> _arr<span style="color:#cccccc">.</span><span style="color:#f08d49">concat</span><span style="color:#cccccc">(</span><span style="color:#cc99cd">this</span><span style="color:#cccccc">.</span>afterCounter<span style="color:#cccccc">)</span><span style="color:#999999">//不同部分的相同算法骨架</span><span style="color:#cc99cd">function</span> <span style="color:#f08d49">baseCount</span><span style="color:#cccccc">(</span>num<span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span>num <span style="color:#67cdcc">+=</span> <span style="color:#f08d49">4</span>num <span style="color:#67cdcc">*=</span> <span style="color:#f08d49">2</span><span style="color:#cc99cd">return</span> num<span style="color:#cccccc">}</span><span style="color:#999999">//循环执行算法队列</span><span style="color:#cc99cd">while</span> <span style="color:#cccccc">(</span>_arr<span style="color:#cccccc">.</span>length <span style="color:#67cdcc">></span> <span style="color:#f08d49">0</span><span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span>_resultnum <span style="color:#67cdcc">=</span> _arr<span style="color:#cccccc">.</span><span style="color:#f08d49">shift</span><span style="color:#cccccc">(</span><span style="color:#cccccc">)</span><span style="color:#cccccc">(</span>_resultnum<span style="color:#cccccc">)</span><span style="color:#cccccc">}</span><span style="color:#cc99cd">return</span> _resultnum
<span style="color:#cccccc">}</span>
<span style="color:#999999">//使用</span>
<span style="color:#cc99cd">var</span> countObject <span style="color:#67cdcc">=</span> <span style="color:#cc99cd">new</span> <span style="color:#f8c555">counter</span><span style="color:#cccccc">(</span><span style="color:#cccccc">)</span>
countObject<span style="color:#cccccc">.</span><span style="color:#f08d49">addBefore</span><span style="color:#cccccc">(</span><span style="color:#cc99cd">function</span><span style="color:#cccccc">(</span>num<span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span>num<span style="color:#67cdcc">--</span><span style="color:#cc99cd">return</span> num
<span style="color:#cccccc">}</span><span style="color:#cccccc">)</span>
countObject<span style="color:#cccccc">.</span><span style="color:#f08d49">addAfter</span><span style="color:#cccccc">(</span><span style="color:#cc99cd">function</span><span style="color:#cccccc">(</span>num<span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span>num <span style="color:#67cdcc">*=</span> <span style="color:#f08d49">2</span><span style="color:#cc99cd">return</span> num
<span style="color:#cccccc">}</span><span style="color:#cccccc">)</span>
countObject<span style="color:#cccccc">.</span><span style="color:#f08d49">count</span><span style="color:#cccccc">(</span><span style="color:#f08d49">10</span><span style="color:#cccccc">)</span>
</code></span></span></span>
这个应用了组合实现模版模式
javascript 的组合与继承
-
组合(推荐)
- javascript 最初没有专门的继承,所以最初 javascript 推崇函数式的编程,然后进行统一组合桥接到一起
- 桥接模式可以看出组合的一种体现,组合的好处是耦合低,方便方法复用,方便扩展
-
继承
- es6 出现 class 与 extend,继承的方式多种多样,但是都是各有弊端
- 模版方法模式可以看出继承的一种体现,继承的好处是可以自动获得父类的内容与接口,方便统一化
#3.4 总结
- 桥接模式
通过独立方法间接的桥接来形成整体功能,这样每个方法都可以被高度复用
- 享元模式
提取出公有部分与私有部分,私有部分作为外部数据传入,从而减少对象数量
- 模版方法模式
当一个功能朝着多样化发展,不妨先定义一个基础的,把具体实现延迟到后面
#4. 提高可扩展性(1)
提高可扩展性的目的
- 面对需求变更,方便更该需求
- 减少代码修改的难度
什么是好的扩展
- 需求的变更,不需要重写
- 代码修改不会引起大规模变动
- 方便加入新模块
#4.1 提高可扩展性的设计模式
# 更好的更改代码
- 适配器模式(接口)
适配器模式的目的:通过写一个适配器,来代替替换
适配器模式的应用场景:面临接口不通用的问题
- 装饰者模式(方法作用)
装饰者模式的目的:不重写方法的扩展方法
装饰者模式的应用场景:放一个方法需要扩展,但是又不好去修改方法
# 解耦你得方法与调用
- 命令模式
命令模式的目的:解耦实现和调用,让双方互不干扰
命令模式的应用场景:调用的命令充满不确性
#4.2 基本结构
# 适配器模式的基本结构
<span style="background-color:#282c34"><span style="color:#2c3e50"><span style="color:#cccccc"><code><span style="color:#cc99cd">var</span> <span style="color:#f08d49">log</span> <span style="color:#67cdcc">=</span> <span style="color:#cc99cd">function</span><span style="color:#cccccc">(</span><span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span><span style="color:#cc99cd">return</span> winodw<span style="color:#cccccc">.</span>console<span style="color:#cccccc">.</span>log
<span style="color:#cccccc">}</span>
</code></span></span></span>
想用 log 来代替 console.log
# 装饰者模式的基本结构
<span style="background-color:#282c34"><span style="color:#2c3e50"><span style="color:#cccccc"><code><span style="color:#999999">// 在一个他人写好的模版a内部调用b,模块为他人写好,不能修改,如何扩展b方法?</span>
<span style="color:#cc99cd">var</span> a <span style="color:#67cdcc">=</span> <span style="color:#cccccc">{</span><span style="color:#f08d49">b</span><span style="color:#67cdcc">:</span> <span style="color:#cc99cd">function</span><span style="color:#cccccc">(</span><span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span><span style="color:#cccccc">}</span>
<span style="color:#cccccc">}</span>
<span style="color:#cc99cd">function</span> <span style="color:#f08d49">myb</span><span style="color:#cccccc">(</span><span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span>a<span style="color:#cccccc">.</span><span style="color:#f08d49">b</span><span style="color:#cccccc">(</span><span style="color:#cccccc">)</span><span style="color:#999999">// 要扩展的方法</span>
<span style="color:#cccccc">}</span>
</code></span></span></span>
我们新建一个自己的方法,在其内部调用 b 方法,并且再执行自己的方法,这样可以在不修改原方法的情况下扩展方法
# 命令模式的基本结构
<span style="background-color:#282c34"><span style="color:#2c3e50"><span style="color:#cccccc"><code> <span style="color:#cc99cd">var</span> command<span style="color:#67cdcc">=</span><span style="color:#cccccc">(</span><span style="color:#cc99cd">function</span><span style="color:#cccccc">(</span><span style="color:#cccccc">)</span><span style="color:#cccccc">{</span><span style="color:#999999">// action中定义了各种方法</span><span style="color:#cc99cd">var</span> action<span style="color:#67cdcc">=</span><span style="color:#cccccc">{</span><span style="color:#cccccc">}</span><span style="color:#999999">// excure可以调用action方法</span><span style="color:#cc99cd">return</span> <span style="color:#cc99cd">function</span> <span style="color:#f08d49">excure</span><span style="color:#cccccc">(</span><span style="color:#cccccc">)</span><span style="color:#cccccc">}</span><span style="color:#cccccc">)</span><span style="color:#cccccc">(</span><span style="color:#cccccc">)</span><span style="color:#999999">// command只需输入命令就可以调用action里的方法</span>
</code></span></span></span>
#4.3 应用示例
#适配器模式示例
框架的变更
需求:目前项目使用的 A 框架,现在改成了 B,2 个框架与十分类似,但是有少数几个方法不同
<span style="background-color:#282c34"><span style="color:#2c3e50"><span style="color:#cccccc"><code><span style="color:#999999">// A框架调用的方式</span>
<span style="color:#f8c555">A</span><span style="color:#cccccc">.</span><span style="color:#f08d49">c</span><span style="color:#cccccc">(</span><span style="color:#cccccc">)</span>
<span style="color:#999999">// 假如我们项目中换成了jQuey,我们不想全部去替换A方法,就用适配器的方法</span>
<span style="color:#f8c555">A</span><span style="color:#cccccc">.</span><span style="color:#f08d49">c</span> <span style="color:#67cdcc">=</span> <span style="color:#cc99cd">function</span><span style="color:#cccccc">(</span><span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span><span style="color:#cc99cd">return</span> $<span style="color:#cccccc">.</span><span style="color:#f08d49">on</span><span style="color:#cccccc">.</span><span style="color:#f08d49">apply</span><span style="color:#cccccc">(</span><span style="color:#cc99cd">this</span><span style="color:#cccccc">.</span>arguments<span style="color:#cccccc">)</span>
<span style="color:#cccccc">}</span>
</code></span></span></span>
参数适配
需求:为了避免参数不适配产生问题,很多框架会有一个参数适配操作
<span style="background-color:#282c34"><span style="color:#2c3e50"><span style="color:#cccccc"><code><span style="color:#999999">// 给参数适配,没传值给默认值</span>
<span style="color:#cc99cd">function</span> <span style="color:#f08d49">f1</span><span style="color:#cccccc">(</span><span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span><span style="color:#cc99cd">var</span> _defalut <span style="color:#67cdcc">=</span> <span style="color:#cccccc">{</span>name<span style="color:#67cdcc">:</span> <span style="color:#7ec699">''</span><span style="color:#cccccc">,</span>color<span style="color:#67cdcc">:</span> <span style="color:#7ec699">''</span><span style="color:#cccccc">}</span><span style="color:#cc99cd">for</span> <span style="color:#cccccc">(</span><span style="color:#cc99cd">var</span> item <span style="color:#cc99cd">in</span> _defalut<span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span>_defalut<span style="color:#cccccc">[</span>item<span style="color:#cccccc">]</span> <span style="color:#67cdcc">=</span> config<span style="color:#cccccc">[</span>item<span style="color:#cccccc">]</span> <span style="color:#67cdcc">||</span> _defalut<span style="color:#cccccc">[</span>item<span style="color:#cccccc">]</span><span style="color:#cccccc">}</span><span style="color:#cc99cd">return</span> _defalut
<span style="color:#cccccc">}</span>
</code></span></span></span>
# 装饰者模式示例
扩展你的已有事件绑定
需求:现在项目改造,需要给 input 标签已经有的事件增加一些操作
<span style="background-color:#282c34"><span style="color:#2c3e50"><span style="color:#cccccc"><code><span style="color:#cc99cd">var</span> <span style="color:#f08d49">decorator</span> <span style="color:#67cdcc">=</span> <span style="color:#cc99cd">function</span><span style="color:#cccccc">(</span>dom<span style="color:#cccccc">,</span> fn<span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span><span style="color:#cc99cd">if</span> <span style="color:#cccccc">(</span><span style="color:#cccccc">(</span><span style="color:#cc99cd">typeof</span> dom<span style="color:#cccccc">.</span>onclick <span style="color:#67cdcc">=</span> <span style="color:#7ec699">'function'</span><span style="color:#cccccc">)</span><span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span><span style="color:#cc99cd">var</span> _old <span style="color:#67cdcc">=</span> dom<span style="color:#cccccc">.</span>onclickdom<span style="color:#cccccc">.</span><span style="color:#f08d49">onclick</span> <span style="color:#67cdcc">=</span> <span style="color:#cc99cd">function</span><span style="color:#cccccc">(</span><span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span><span style="color:#f08d49">_old</span><span style="color:#cccccc">(</span><span style="color:#cccccc">)</span><span style="color:#f08d49">fn</span><span style="color:#cccccc">(</span><span style="color:#cccccc">)</span><span style="color:#cccccc">}</span><span style="color:#cccccc">}</span>
<span style="color:#cccccc">}</span>
<span style="color:#f08d49">decorator</span><span style="color:#cccccc">(</span>document<span style="color:#cccccc">.</span><span style="color:#f08d49">getElementById</span><span style="color:#cccccc">(</span><span style="color:#7ec699">'dom1'</span><span style="color:#cccccc">)</span><span style="color:#cccccc">,</span> <span style="color:#cc99cd">function</span><span style="color:#cccccc">(</span><span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span><span style="color:#999999">// 自己的操作</span>
<span style="color:#cccccc">}</span><span style="color:#cccccc">)</span>
</code></span></span></span>
Vue 的数组监听
需求:vue 中利用 defineProperty 可以监听对象,那么数组怎么办
<span style="background-color:#282c34"><span style="color:#2c3e50"><span style="color:#cccccc"><code><span style="color:#cc99cd">var</span> arrayProto <span style="color:#67cdcc">=</span> <span style="color:#f8c555">Array</span><span style="color:#cccccc">.</span>prototype
<span style="color:#cc99cd">var</span> arrayMethods <span style="color:#67cdcc">=</span> Object<span style="color:#cccccc">.</span><span style="color:#f08d49">create</span><span style="color:#cccccc">(</span>arrayProto<span style="color:#cccccc">)</span>
<span style="color:#cc99cd">var</span> methodsToPatch <span style="color:#67cdcc">=</span> <span style="color:#cccccc">[</span><span style="color:#7ec699">'push'</span><span style="color:#cccccc">,</span><span style="color:#7ec699">'pop'</span><span style="color:#cccccc">,</span><span style="color:#7ec699">'unshift'</span><span style="color:#cccccc">,</span><span style="color:#7ec699">'shift'</span><span style="color:#cccccc">,</span><span style="color:#7ec699">'splice'</span><span style="color:#cccccc">,</span><span style="color:#7ec699">'resverse'</span><span style="color:#cccccc">,</span><span style="color:#7ec699">'sort'</span>
<span style="color:#cccccc">]</span>methodsToPatch<span style="color:#cccccc">.</span><span style="color:#f08d49">forEach</span><span style="color:#cccccc">(</span>method <span style="color:#67cdcc">=></span> <span style="color:#cccccc">{</span><span style="color:#cc99cd">var</span> original <span style="color:#67cdcc">=</span> arrayMethods<span style="color:#cccccc">[</span>method<span style="color:#cccccc">]</span>object<span style="color:#cccccc">.</span><span style="color:#f08d49">defineProperty</span><span style="color:#cccccc">(</span>arrayMethods<span style="color:#cccccc">,</span> method<span style="color:#cccccc">,</span> <span style="color:#cccccc">{</span><span style="color:#f08d49">value</span><span style="color:#cccccc">(</span><span style="color:#67cdcc">...</span>args<span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span><span style="color:#cc99cd">const</span> result <span style="color:#67cdcc">=</span> <span style="color:#f08d49">original</span><span style="color:#cccccc">.</span><span style="color:#f08d49">apply</span><span style="color:#cccccc">(</span><span style="color:#cc99cd">this</span><span style="color:#cccccc">,</span> args<span style="color:#cccccc">)</span>dep<span style="color:#cccccc">.</span><span style="color:#f08d49">notify</span><span style="color:#cccccc">(</span><span style="color:#cccccc">)</span><span style="color:#cc99cd">return</span> result<span style="color:#cccccc">}</span><span style="color:#cccccc">}</span><span style="color:#cccccc">)</span>
<span style="color:#cccccc">}</span><span style="color:#cccccc">)</span>
</code></span></span></span>
装饰者模式,拿到老方法,调用老方法,组成新方法
# 命令模式示例
需求:封装一系列的 canvas 绘图命令
<span style="background-color:#282c34"><span style="color:#2c3e50"><span style="color:#cccccc"><code><span style="color:#cc99cd">var</span> <span style="color:#f08d49">myCanvas</span> <span style="color:#67cdcc">=</span> <span style="color:#cc99cd">function</span><span style="color:#cccccc">(</span><span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span><span style="color:#cccccc">}</span>
myCanvas<span style="color:#cccccc">.</span>prototype<span style="color:#cccccc">.</span><span style="color:#f08d49">drawCircle</span> <span style="color:#67cdcc">=</span> <span style="color:#cc99cd">function</span><span style="color:#cccccc">(</span><span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span><span style="color:#cccccc">}</span>
myCanvas<span style="color:#cccccc">.</span>prototype<span style="color:#cccccc">.</span><span style="color:#f08d49">drawRect</span> <span style="color:#67cdcc">=</span> <span style="color:#cc99cd">function</span><span style="color:#cccccc">(</span><span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span><span style="color:#cccccc">}</span><span style="color:#cc99cd">var</span> canvasComand <span style="color:#67cdcc">=</span> <span style="color:#cccccc">(</span><span style="color:#cc99cd">function</span><span style="color:#cccccc">(</span><span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span><span style="color:#cc99cd">var</span> action <span style="color:#67cdcc">=</span> <span style="color:#cccccc">{</span><span style="color:#f08d49">drawCircle</span><span style="color:#67cdcc">:</span> <span style="color:#cc99cd">function</span><span style="color:#cccccc">(</span>config<span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span><span style="color:#cccccc">}</span><span style="color:#cccccc">,</span><span style="color:#f08d49">drawRect</span><span style="color:#67cdcc">:</span> <span style="color:#cc99cd">function</span><span style="color:#cccccc">(</span>config<span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span><span style="color:#cccccc">}</span><span style="color:#cccccc">}</span><span style="color:#cc99cd">return</span> <span style="color:#cc99cd">function</span> <span style="color:#f08d49">excute</span><span style="color:#cccccc">(</span>commander<span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span>commander<span style="color:#cccccc">.</span><span style="color:#f08d49">forEach</span><span style="color:#cccccc">(</span>item <span style="color:#67cdcc">=></span> <span style="color:#cccccc">{</span>action<span style="color:#cccccc">[</span>item<span style="color:#cccccc">.</span>command<span style="color:#cccccc">]</span><span style="color:#cccccc">(</span>item<span style="color:#cccccc">.</span>config<span style="color:#cccccc">)</span><span style="color:#cccccc">}</span><span style="color:#cccccc">)</span><span style="color:#cccccc">}</span>
<span style="color:#cccccc">}</span><span style="color:#cccccc">)</span><span style="color:#cccccc">(</span><span style="color:#cccccc">)</span><span style="color:#f08d49">myCanvas</span><span style="color:#cccccc">(</span><span style="color:#cccccc">[</span><span style="color:#cccccc">{</span> command<span style="color:#67cdcc">:</span> <span style="color:#7ec699">'drawReact'</span><span style="color:#cccccc">,</span> config<span style="color:#67cdcc">:</span> <span style="color:#cccccc">{</span><span style="color:#cccccc">}</span> <span style="color:#cccccc">}</span><span style="color:#cccccc">]</span><span style="color:#cccccc">)</span>
</code></span></span></span>
-
用户只管输入他要的命令,不用关心 api
-
命令和实现解耦,无论命令发生变动,还是实现发生变动,都不会彼此影响
绘制随数量图片
需求:需要做一个画廊,图片数量和排列顺序随机
<span style="background-color:#282c34"><span style="color:#2c3e50"><span style="color:#cccccc"><code><span style="color:#cc99cd">var</span> createImg <span style="color:#67cdcc">=</span> <span style="color:#cccccc">(</span><span style="color:#cc99cd">function</span><span style="color:#cccccc">(</span><span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span><span style="color:#cc99cd">var</span> action <span style="color:#67cdcc">=</span> <span style="color:#cccccc">{</span><span style="color:#f08d49">create</span><span style="color:#67cdcc">:</span> <span style="color:#cc99cd">function</span><span style="color:#cccccc">(</span>obj<span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span><span style="color:#cc99cd">var</span> htmlArr <span style="color:#67cdcc">=</span> <span style="color:#cccccc">[</span><span style="color:#cccccc">]</span><span style="color:#cc99cd">var</span> _htmlstring <span style="color:#67cdcc">=</span> <span style="color:#7ec699">''</span><span style="color:#cc99cd">var</span> _htmlTemplate <span style="color:#67cdcc">=</span><span style="color:#7ec699">"<div><img src='{{img-url}}' /></div><h2>{{title}}</h2>"</span><span style="color:#cc99cd">var</span> displayWay <span style="color:#67cdcc">=</span> <span style="color:#cccccc">{</span><span style="color:#f08d49">normal</span><span style="color:#67cdcc">:</span> <span style="color:#cc99cd">function</span><span style="color:#cccccc">(</span>arr<span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span><span style="color:#cc99cd">return</span> arr<span style="color:#cccccc">}</span><span style="color:#cccccc">,</span><span style="color:#f08d49">reverse</span><span style="color:#67cdcc">:</span> <span style="color:#cc99cd">function</span><span style="color:#cccccc">(</span>arr<span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span><span style="color:#cc99cd">return</span> arr<span style="color:#cccccc">.</span>reverse<span style="color:#cccccc">}</span><span style="color:#cccccc">}</span>obj<span style="color:#cccccc">.</span>imgArr<span style="color:#cccccc">.</span><span style="color:#f08d49">forEach</span><span style="color:#cccccc">(</span>img <span style="color:#67cdcc">=></span> <span style="color:#cccccc">{</span><span style="color:#cc99cd">var</span> _html_html <span style="color:#67cdcc">=</span> _htmlTemplate<span style="color:#cccccc">.</span><span style="color:#f08d49">replace</span><span style="color:#cccccc">(</span><span style="color:#7ec699">'{{img-url}}'</span><span style="color:#cccccc">,</span> img<span style="color:#cccccc">.</span>img<span style="color:#cccccc">)</span><span style="color:#cccccc">.</span><span style="color:#f08d49">replace</span><span style="color:#cccccc">(</span><span style="color:#7ec699">'{{title}}'</span><span style="color:#cccccc">,</span> img<span style="color:#cccccc">.</span>title<span style="color:#cccccc">)</span>htmlArr<span style="color:#cccccc">.</span><span style="color:#f08d49">push</span><span style="color:#cccccc">(</span>_html<span style="color:#cccccc">)</span><span style="color:#cccccc">}</span><span style="color:#cccccc">)</span>htmlArr <span style="color:#67cdcc">=</span> displayWay<span style="color:#cccccc">[</span>obj<span style="color:#cccccc">.</span>type<span style="color:#cccccc">]</span><span style="color:#cccccc">(</span>htmlArr<span style="color:#cccccc">)</span>_htmlstring <span style="color:#67cdcc">=</span> htmlArr<span style="color:#cccccc">.</span><span style="color:#f08d49">join</span><span style="color:#cccccc">(</span><span style="color:#7ec699">''</span><span style="color:#cccccc">)</span><span style="color:#cc99cd">return</span> <span style="color:#7ec699">'<div>'</span> <span style="color:#67cdcc">+</span> _htmlstring <span style="color:#67cdcc">+</span> <span style="color:#7ec699">'</div>'</span><span style="color:#cccccc">}</span><span style="color:#cccccc">,</span><span style="color:#f08d49">display</span><span style="color:#67cdcc">:</span> <span style="color:#cc99cd">function</span><span style="color:#cccccc">(</span>obj<span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span><span style="color:#cc99cd">var</span> _html <span style="color:#67cdcc">=</span> <span style="color:#cc99cd">this</span><span style="color:#cccccc">.</span><span style="color:#f08d49">create</span><span style="color:#cccccc">(</span>obj<span style="color:#cccccc">)</span>obj<span style="color:#cccccc">.</span>target<span style="color:#cccccc">.</span>innerHTML <span style="color:#67cdcc">=</span> _html<span style="color:#cccccc">}</span><span style="color:#cccccc">}</span><span style="color:#cc99cd">return</span> <span style="color:#cc99cd">function</span> <span style="color:#f08d49">excute</span><span style="color:#cccccc">(</span>obj<span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span><span style="color:#cc99cd">var</span> _default <span style="color:#67cdcc">=</span> <span style="color:#cccccc">{</span>imgArr<span style="color:#67cdcc">:</span> <span style="color:#cccccc">[</span><span style="color:#cccccc">{</span> img<span style="color:#67cdcc">:</span> <span style="color:#7ec699">'xxxx'</span><span style="color:#cccccc">,</span> title<span style="color:#67cdcc">:</span> <span style="color:#7ec699">'default title'</span> <span style="color:#cccccc">}</span><span style="color:#cccccc">]</span><span style="color:#cccccc">,</span>type<span style="color:#67cdcc">:</span> <span style="color:#7ec699">'normal'</span><span style="color:#cccccc">,</span>target<span style="color:#67cdcc">:</span> document<span style="color:#cccccc">.</span>body<span style="color:#cccccc">}</span><span style="color:#cc99cd">for</span> <span style="color:#cccccc">(</span><span style="color:#cc99cd">var</span> item <span style="color:#cc99cd">in</span> _default<span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span>_default<span style="color:#cccccc">[</span>item<span style="color:#cccccc">]</span> <span style="color:#67cdcc">=</span> obj<span style="color:#cccccc">[</span>item<span style="color:#cccccc">]</span> <span style="color:#67cdcc">||</span> _default<span style="color:#cccccc">[</span>item<span style="color:#cccccc">]</span><span style="color:#cccccc">}</span>action<span style="color:#cccccc">.</span><span style="color:#f08d49">display</span><span style="color:#cccccc">(</span>_default<span style="color:#cccccc">)</span><span style="color:#cccccc">}</span>
<span style="color:#cccccc">}</span><span style="color:#cccccc">)</span><span style="color:#cccccc">(</span><span style="color:#cccccc">)</span>
<span style="color:#f08d49">createImg</span><span style="color:#cccccc">(</span><span style="color:#cccccc">{</span>imgArr<span style="color:#67cdcc">:</span> <span style="color:#cccccc">[</span><span style="color:#cccccc">{</span> img<span style="color:#67cdcc">:</span> <span style="color:#7ec699">'xxxx'</span><span style="color:#cccccc">,</span> title<span style="color:#67cdcc">:</span> <span style="color:#7ec699">'default title1'</span> <span style="color:#cccccc">}</span><span style="color:#cccccc">,</span><span style="color:#cccccc">{</span> img<span style="color:#67cdcc">:</span> <span style="color:#7ec699">'xxxx'</span><span style="color:#cccccc">,</span> title<span style="color:#67cdcc">:</span> <span style="color:#7ec699">'default title2'</span> <span style="color:#cccccc">}</span><span style="color:#cccccc">]</span><span style="color:#cccccc">,</span>type<span style="color:#67cdcc">:</span> <span style="color:#7ec699">'normal'</span>
<span style="color:#cccccc">}</span><span style="color:#cccccc">)</span>
</code></span></span></span>
数据-> excute 命令解析层 -> 调用 api
#4.4 总结
- 适配器模式
当面临两个新老模块间接口 api 不匹配,可以用适配来转化 api
- 装饰者模式
当老的方法,不方便去直接修改,可以通装饰者来增加功能
- 命令模式
解耦实现与具体命令,让实现端和命令端扩展的都更轻松
#5. 提高可扩展性(2)
提高整体项目可扩展性的核心
-
低耦合
-
良好的组织沟通方式
#5.1 提高可扩展性的设计模式
#应对需求上的变更
- 观察者模式(事件绑定是典型的观察者模式,比如 dom 上监视点击了事件,点击事件触发以后就去做这个点击事件)
观察者模式的目的:减少对象间的耦合,来提高可扩展性
观察者模式的应用场景:当两个模块直接沟通会增加它们的耦合性时
- 职责链模式
职责链模式的目的:为了避免请求发送者与多个请求处理者耦合在一起,形成一个链条
组合模式的应用场景:把操作分隔成一系列模块,每个模块只处理自己的事情
应对需求上的变更
访问者模式的目的:解耦数据结构与数据操作
访问者模式的应用场景:数据结构不希望与操作有关联
#5.2 基本结构
# 观察者的基本结构
<span style="background-color:#282c34"><span style="color:#2c3e50"><span style="color:#cccccc"><code><span style="color:#cc99cd">function</span> observe <span style="color:#cccccc">{</span><span style="color:#cc99cd">this</span><span style="color:#cccccc">.</span>message<span style="color:#67cdcc">=</span><span style="color:#cccccc">{</span><span style="color:#cccccc">}</span>
<span style="color:#cccccc">}</span>observe<span style="color:#cccccc">.</span>prototype<span style="color:#cccccc">.</span><span style="color:#f08d49">regist</span><span style="color:#67cdcc">=</span><span style="color:#cc99cd">function</span><span style="color:#cccccc">(</span>type<span style="color:#cccccc">,</span>fn<span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span><span style="color:#cc99cd">this</span><span style="color:#cccccc">.</span>message<span style="color:#cccccc">[</span>type<span style="color:#cccccc">]</span><span style="color:#67cdcc">=</span>fn
<span style="color:#cccccc">}</span>observe<span style="color:#cccccc">.</span>prototype<span style="color:#cccccc">.</span><span style="color:#f08d49">fire</span><span style="color:#67cdcc">=</span><span style="color:#cc99cd">function</span><span style="color:#cccccc">(</span>type<span style="color:#cccccc">)</span><span style="color:#cccccc">{</span><span style="color:#cc99cd">this</span><span style="color:#cccccc">.</span>message<span style="color:#cccccc">[</span>type<span style="color:#cccccc">]</span><span style="color:#cccccc">(</span><span style="color:#cccccc">)</span>
<span style="color:#cccccc">}</span>observe<span style="color:#cccccc">.</span>prototype<span style="color:#cccccc">.</span><span style="color:#f08d49">remove</span><span style="color:#67cdcc">=</span><span style="color:#cc99cd">function</span><span style="color:#cccccc">(</span>type<span style="color:#cccccc">)</span><span style="color:#cccccc">{</span><span style="color:#cc99cd">this</span><span style="color:#cccccc">.</span>message<span style="color:#cccccc">[</span>type<span style="color:#cccccc">]</span><span style="color:#67cdcc">=</span><span style="color:#cc99cd">null</span>
<span style="color:#cccccc">}</span>
</code></span></span></span>
- 定义一个中转观察者,两个模块之间不直接沟通,而是通过观察者,一般使用与不方便直接沟通,或者异步操作
# 职责链模式的基本结构
<span style="background-color:#282c34"><span style="color:#2c3e50"><span style="color:#cccccc"><code><span style="color:#cc99cd">function</span> <span style="color:#f08d49">mode1</span><span style="color:#cccccc">(</span><span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span><span style="color:#cccccc">}</span><span style="color:#cc99cd">function</span> <span style="color:#f08d49">mode2</span><span style="color:#cccccc">(</span><span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span><span style="color:#cccccc">}</span><span style="color:#cc99cd">function</span> <span style="color:#f08d49">mode3</span><span style="color:#cccccc">(</span><span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span><span style="color:#cccccc">}</span>_result <span style="color:#67cdcc">=</span> <span style="color:#f08d49">mode1</span><span style="color:#cccccc">(</span>_result<span style="color:#cccccc">)</span>
_result <span style="color:#67cdcc">=</span> <span style="color:#f08d49">mode2</span><span style="color:#cccccc">(</span>_result<span style="color:#cccccc">)</span>
_result <span style="color:#67cdcc">=</span> <span style="color:#f08d49">mode3</span><span style="color:#cccccc">(</span>_result<span style="color:#cccccc">)</span>
</code></span></span></span>
- 把要做的事情组织为一条有序的链条,通过再这条链条传递消息来完成功能,适用于不设计到赋值异步操作
#访问者模式的基本结构
<span style="background-color:#282c34"><span style="color:#2c3e50"><span style="color:#cccccc"><code><span style="color:#cc99cd">var</span> data <span style="color:#67cdcc">=</span> <span style="color:#cccccc">[</span><span style="color:#cccccc">]</span><span style="color:#cc99cd">var</span> <span style="color:#f08d49">handler</span> <span style="color:#67cdcc">=</span> <span style="color:#cc99cd">function</span><span style="color:#cccccc">(</span><span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span><span style="color:#cccccc">}</span>handler<span style="color:#cccccc">.</span>prototype<span style="color:#cccccc">.</span><span style="color:#f08d49">get</span> <span style="color:#67cdcc">=</span> <span style="color:#cc99cd">function</span><span style="color:#cccccc">(</span><span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span><span style="color:#cccccc">}</span><span style="color:#cc99cd">var</span> <span style="color:#f08d49">vistor</span> <span style="color:#67cdcc">=</span> <span style="color:#cc99cd">function</span><span style="color:#cccccc">(</span>handler<span style="color:#cccccc">,</span> data<span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span>handler<span style="color:#cccccc">.</span><span style="color:#f08d49">get</span><span style="color:#cccccc">(</span>data<span style="color:#cccccc">)</span>
<span style="color:#cccccc">}</span>
</code></span></span></span>
- 通过定义一个访问者,代替直接访问对象,来减少两个对象之间的耦合
#5.3 应用示例
# 观察者模式示例
多人合作的问题
需求:现在假设 A 工程师写了首页模块,然后 B 工程师写了评论模块。现在要把评论展示在首页
<span style="background-color:#282c34"><span style="color:#2c3e50"><span style="color:#cccccc"><code><span style="color:#cc99cd">function</span> observe <span style="color:#cccccc">{</span><span style="color:#cc99cd">this</span><span style="color:#cccccc">.</span>message<span style="color:#67cdcc">=</span><span style="color:#cccccc">{</span><span style="color:#cccccc">}</span>
<span style="color:#cccccc">}</span>observe<span style="color:#cccccc">.</span>prototype<span style="color:#cccccc">.</span><span style="color:#f08d49">regist</span><span style="color:#67cdcc">=</span><span style="color:#cc99cd">function</span><span style="color:#cccccc">(</span>type<span style="color:#cccccc">,</span>fn<span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span><span style="color:#cc99cd">this</span><span style="color:#cccccc">.</span>message<span style="color:#cccccc">[</span>type<span style="color:#cccccc">]</span><span style="color:#67cdcc">=</span>fn
<span style="color:#cccccc">}</span>observe<span style="color:#cccccc">.</span>prototype<span style="color:#cccccc">.</span><span style="color:#f08d49">fire</span><span style="color:#67cdcc">=</span><span style="color:#cc99cd">function</span><span style="color:#cccccc">(</span>type<span style="color:#cccccc">)</span><span style="color:#cccccc">{</span><span style="color:#cc99cd">this</span><span style="color:#cccccc">.</span>message<span style="color:#cccccc">[</span>type<span style="color:#cccccc">]</span><span style="color:#cccccc">(</span><span style="color:#cccccc">)</span>
<span style="color:#cccccc">}</span><span style="color:#cc99cd">function</span> <span style="color:#f08d49">comment</span> <span style="color:#cccccc">(</span><span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span><span style="color:#cc99cd">var</span> self<span style="color:#67cdcc">=</span><span style="color:#cc99cd">this</span><span style="color:#cccccc">;</span><span style="color:#cc99cd">this</span><span style="color:#cccccc">.</span>commentList<span style="color:#67cdcc">=</span><span style="color:#cccccc">[</span><span style="color:#cccccc">{</span>type<span style="color:#67cdcc">:</span><span style="color:#7ec699">'hot'</span><span style="color:#cccccc">,</span>content<span style="color:#67cdcc">:</span><span style="color:#7ec699">'xxxx'</span><span style="color:#cccccc">}</span><span style="color:#cccccc">]</span><span style="color:#cccccc">;</span>
<span style="color:#999999">// 注册事件</span>
observeOb<span style="color:#cccccc">.</span><span style="color:#f08d49">regist</span><span style="color:#cccccc">(</span><span style="color:#7ec699">'gotHot'</span><span style="color:#cccccc">,</span><span style="color:#cc99cd">function</span><span style="color:#cccccc">(</span><span style="color:#cccccc">)</span><span style="color:#cccccc">{</span><span style="color:#cc99cd">var</span> _arr<span style="color:#67cdcc">=</span><span style="color:#cccccc">[</span><span style="color:#cccccc">]</span><span style="color:#cccccc">;</span>self<span style="color:#cccccc">.</span>commentList<span style="color:#cccccc">.</span><span style="color:#f08d49">forEach</span><span style="color:#cccccc">(</span><span style="color:#cccccc">(</span>item<span style="color:#cccccc">)</span><span style="color:#67cdcc">=></span><span style="color:#cccccc">{</span><span style="color:#cc99cd">if</span><span style="color:#cccccc">(</span>item<span style="color:#cccccc">.</span>type<span style="color:#67cdcc">===</span><span style="color:#7ec699">'hot'</span><span style="color:#cccccc">)</span><span style="color:#cccccc">{</span>_arr<span style="color:#cccccc">.</span><span style="color:#f08d49">push</span><span style="color:#cccccc">(</span>item<span style="color:#cccccc">)</span><span style="color:#cccccc">}</span><span style="color:#cccccc">}</span><span style="color:#cccccc">)</span><span style="color:#cc99cd">return</span> _arr
<span style="color:#cccccc">}</span><span style="color:#cccccc">)</span><span style="color:#cccccc">}</span>
<span style="color:#999999">// 调用事件</span>
<span style="color:#cc99cd">var</span> _arr<span style="color:#67cdcc">=</span>observeOb<span style="color:#cccccc">.</span><span style="color:#f08d49">fire</span><span style="color:#cccccc">(</span><span style="color:#7ec699">'gotHot'</span><span style="color:#cccccc">)</span></code></span></span></span>
一个转盘
需求:有一个转盘应用,每转一圈,速度加快
<span style="background-color:#282c34"><span style="color:#2c3e50"><span style="color:#cccccc"><code><span style="color:#cc99cd">function</span> observe <span style="color:#cccccc">{</span><span style="color:#cc99cd">this</span><span style="color:#cccccc">.</span>message<span style="color:#67cdcc">=</span><span style="color:#cccccc">{</span><span style="color:#cccccc">}</span>
<span style="color:#cccccc">}</span>observe<span style="color:#cccccc">.</span>prototype<span style="color:#cccccc">.</span><span style="color:#f08d49">regist</span><span style="color:#67cdcc">=</span><span style="color:#cc99cd">function</span><span style="color:#cccccc">(</span>type<span style="color:#cccccc">,</span>fn<span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span><span style="color:#cc99cd">this</span><span style="color:#cccccc">.</span>message<span style="color:#cccccc">[</span>type<span style="color:#cccccc">]</span><span style="color:#67cdcc">=</span>fn
<span style="color:#cccccc">}</span>observe<span style="color:#cccccc">.</span>prototype<span style="color:#cccccc">.</span><span style="color:#f08d49">fire</span><span style="color:#67cdcc">=</span><span style="color:#cc99cd">function</span><span style="color:#cccccc">(</span>type<span style="color:#cccccc">)</span><span style="color:#cccccc">{</span><span style="color:#cc99cd">this</span><span style="color:#cccccc">.</span>message<span style="color:#cccccc">[</span>type<span style="color:#cccccc">]</span><span style="color:#cccccc">(</span><span style="color:#cccccc">)</span>
<span style="color:#cccccc">}</span><span style="color:#cc99cd">var</span> observeOb<span style="color:#67cdcc">=</span><span style="color:#cc99cd">new</span> <span style="color:#f8c555">observe</span><span style="color:#cccccc">(</span><span style="color:#cccccc">)</span><span style="color:#999999">// 初始化html=> 最终结果选定 => 运动结果 => 运动控制</span><span style="color:#cc99cd">var</span> _domArr<span style="color:#67cdcc">=</span><span style="color:#cccccc">[</span><span style="color:#cccccc">]</span><span style="color:#cc99cd">function</span> <span style="color:#f08d49">htmlInit</span> <span style="color:#cccccc">(</span>target<span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span><span style="color:#cc99cd">for</span><span style="color:#cccccc">(</span><span style="color:#cc99cd">let</span> i <span style="color:#67cdcc">=</span><span style="color:#f08d49">0</span><span style="color:#cccccc">;</span>i<span style="color:#67cdcc"><</span><span style="color:#f08d49">9</span><span style="color:#cccccc">;</span>i<span style="color:#67cdcc">++</span><span style="color:#cccccc">)</span><span style="color:#cccccc">{</span><span style="color:#cc99cd">var</span> _div<span style="color:#67cdcc">=</span>document<span style="color:#cccccc">.</span><span style="color:#f08d49">createElement</span><span style="color:#cccccc">(</span><span style="color:#7ec699">'div'</span><span style="color:#cccccc">)</span>_div<span style="color:#cccccc">.</span>innerHTML<span style="color:#67cdcc">=</span>i_div<span style="color:#cccccc">.</span><span style="color:#f08d49">setAttribute</span><span style="color:#cccccc">(</span><span style="color:#7ec699">'class'</span><span style="color:#cccccc">,</span><span style="color:#7ec699">'item'</span><span style="color:#cccccc">)</span>target<span style="color:#cccccc">.</span><span style="color:#f08d49">appendChild</span><span style="color:#cccccc">(</span>_div<span style="color:#cccccc">)</span>_domArr<span style="color:#cccccc">.</span><span style="color:#f08d49">push</span><span style="color:#cccccc">(</span>_div<span style="color:#cccccc">)</span><span style="color:#cccccc">}</span>
<span style="color:#cccccc">}</span><span style="color:#cc99cd">function</span> <span style="color:#f08d49">getFinal</span><span style="color:#cccccc">(</span><span style="color:#cccccc">)</span><span style="color:#cccccc">{</span><span style="color:#cc99cd">var</span> _num<span style="color:#67cdcc">=</span>Math<span style="color:#cccccc">.</span><span style="color:#f08d49">random</span><span style="color:#cccccc">(</span><span style="color:#cccccc">)</span><span style="color:#67cdcc">*</span><span style="color:#f08d49">10</span><span style="color:#67cdcc">+</span><span style="color:#f08d49">40</span><span style="color:#cc99cd">return</span> Math<span style="color:#cccccc">.</span><span style="color:#f08d49">floor</span><span style="color:#cccccc">(</span>_num<span style="color:#cccccc">,</span><span style="color:#f08d49">0</span><span style="color:#cccccc">)</span>
<span style="color:#cccccc">}</span>
<span style="color:#999999">// 运动模块</span>
<span style="color:#cc99cd">function</span> <span style="color:#f08d49">mover</span> <span style="color:#cccccc">(</span>moveConfig<span style="color:#cccccc">)</span><span style="color:#cccccc">{</span><span style="color:#cc99cd">var</span> nowIn<span style="color:#67cdcc">=</span><span style="color:#f08d49">0</span><span style="color:#cccccc">;</span><span style="color:#cc99cd">var</span> removeNum<span style="color:#67cdcc">=</span><span style="color:#f08d49">9</span><span style="color:#cccccc">;</span><span style="color:#cc99cd">var</span> timer<span style="color:#67cdcc">=</span><span style="color:#f08d49">setInterval</span><span style="color:#cccccc">(</span><span style="color:#cccccc">(</span><span style="color:#cccccc">)</span><span style="color:#67cdcc">=></span><span style="color:#cccccc">{</span><span style="color:#cc99cd">if</span><span style="color:#cccccc">(</span>nowIn<span style="color:#67cdcc">!=</span><span style="color:#f08d49">0</span><span style="color:#cccccc">)</span><span style="color:#cccccc">{</span>removeNum<span style="color:#67cdcc">=</span>nowIn<span style="color:#67cdcc">-</span><span style="color:#f08d49">1</span><span style="color:#cccccc">}</span>_domArr<span style="color:#cccccc">[</span>removeNum<span style="color:#cccccc">]</span><span style="color:#cccccc">.</span><span style="color:#f08d49">setAttribute</span><span style="color:#cccccc">(</span><span style="color:#7ec699">'class'</span><span style="color:#cccccc">,</span><span style="color:#7ec699">'item'</span><span style="color:#cccccc">)</span>_domArr<span style="color:#cccccc">[</span>nowIn<span style="color:#cccccc">]</span><span style="color:#cccccc">.</span><span style="color:#f08d49">setAttribute</span><span style="color:#cccccc">(</span><span style="color:#7ec699">'class'</span><span style="color:#cccccc">,</span><span style="color:#7ec699">'item item-on'</span><span style="color:#cccccc">)</span>nowIn<span style="color:#67cdcc">++</span><span style="color:#cc99cd">if</span><span style="color:#cccccc">(</span>nowIn<span style="color:#67cdcc">==</span>moveConfig<span style="color:#cccccc">.</span>moveTime<span style="color:#cccccc">)</span><span style="color:#cccccc">{</span><span style="color:#f08d49">clearInterval</span><span style="color:#cccccc">(</span>timer<span style="color:#cccccc">)</span><span style="color:#cc99cd">if</span><span style="color:#cccccc">(</span>moveConfig<span style="color:#cccccc">.</span>moveTime<span style="color:#67cdcc">==</span><span style="color:#f08d49">10</span><span style="color:#cccccc">)</span><span style="color:#cccccc">{</span>observeOb<span style="color:#cccccc">.</span><span style="color:#f08d49">fire</span><span style="color:#cccccc">(</span><span style="color:#7ec699">'finish'</span><span style="color:#cccccc">)</span><span style="color:#cccccc">}</span><span style="color:#cccccc">}</span><span style="color:#cccccc">}</span><span style="color:#cccccc">,</span>moveConfig<span style="color:#cccccc">.</span>speed<span style="color:#cccccc">)</span>
<span style="color:#cccccc">}</span><span style="color:#cc99cd">function</span> <span style="color:#f08d49">moveControll</span> <span style="color:#cccccc">(</span><span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span><span style="color:#cc99cd">var</span> final<span style="color:#67cdcc">=</span><span style="color:#f08d49">getFinal</span><span style="color:#cccccc">(</span><span style="color:#cccccc">)</span><span style="color:#cc99cd">var</span> _circle<span style="color:#67cdcc">=</span>Math<span style="color:#cccccc">.</span><span style="color:#f08d49">floor</span><span style="color:#cccccc">(</span>final<span style="color:#67cdcc">/</span><span style="color:#f08d49">10</span><span style="color:#cccccc">,</span><span style="color:#f08d49">0</span><span style="color:#cccccc">)</span><span style="color:#cc99cd">var</span> stopNum<span style="color:#67cdcc">=</span>final<span style="color:#67cdcc">%</span><span style="color:#f08d49">10</span><span style="color:#cc99cd">var</span> _speed<span style="color:#67cdcc">=</span><span style="color:#f08d49">2000</span><span style="color:#cc99cd">var</span> _runCircle<span style="color:#67cdcc">=</span><span style="color:#f08d49">0</span><span style="color:#f08d49">mover</span><span style="color:#cccccc">(</span><span style="color:#cccccc">{</span>moveTime<span style="color:#67cdcc">:</span><span style="color:#f08d49">10</span><span style="color:#cccccc">,</span>speed<span style="color:#67cdcc">:</span>_speed<span style="color:#cccccc">}</span><span style="color:#cccccc">)</span>observeOb<span style="color:#cccccc">.</span><span style="color:#f08d49">regist</span><span style="color:#cccccc">(</span><span style="color:#7ec699">'finish'</span><span style="color:#cccccc">,</span><span style="color:#f08d49">fucntion</span><span style="color:#cccccc">(</span><span style="color:#cccccc">)</span><span style="color:#cccccc">{</span><span style="color:#cc99cd">var</span> _time<span style="color:#67cdcc">=</span><span style="color:#f08d49">0</span><span style="color:#cccccc">;</span>_speed<span style="color:#67cdcc">-=</span><span style="color:#f08d49">50</span><span style="color:#cccccc">;</span>_runCircle<span style="color:#67cdcc">++</span><span style="color:#cccccc">;</span><span style="color:#cc99cd">if</span><span style="color:#cccccc">(</span>_runCircle<span style="color:#67cdcc"><=</span>_circle<span style="color:#cccccc">)</span><span style="color:#cccccc">{</span>_time<span style="color:#67cdcc">=</span><span style="color:#f08d49">0</span><span style="color:#cccccc">}</span><span style="color:#cc99cd">else</span> <span style="color:#cccccc">{</span>_time<span style="color:#67cdcc">=</span>stopNum<span style="color:#cccccc">}</span><span style="color:#f08d49">mover</span><span style="color:#cccccc">(</span><span style="color:#cccccc">{</span>moveTime<span style="color:#67cdcc">:</span>_time<span style="color:#cccccc">,</span>speed<span style="color:#67cdcc">:</span>_speed<span style="color:#cccccc">}</span><span style="color:#cccccc">)</span><span style="color:#cccccc">}</span><span style="color:#cccccc">)</span>
<span style="color:#cccccc">}</span><span style="color:#f08d49">htmlInit</span><span style="color:#cccccc">(</span>document<span style="color:#cccccc">.</span><span style="color:#f08d49">getElementById</span><span style="color:#cccccc">(</span><span style="color:#7ec699">'app'</span><span style="color:#cccccc">)</span><span style="color:#cccccc">)</span>
<span style="color:#f08d49">moveControll</span><span style="color:#cccccc">(</span><span style="color:#cccccc">)</span>
</code></span></span></span>
#职责链模式示例
Axios 的拦截器
需求:axios 拦截器的设计,大家可以看成一个用给职责链的思想去处理请求
<span style="background-color:#282c34"><span style="color:#2c3e50"><span style="color:#cccccc"><code><span style="color:#cc99cd">function</span> <span style="color:#f08d49">axios</span><span style="color:#cccccc">(</span><span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span><span style="color:#cc99cd">this</span><span style="color:#cccccc">.</span>interceptors <span style="color:#67cdcc">=</span> <span style="color:#cccccc">{</span>request<span style="color:#67cdcc">:</span> <span style="color:#cc99cd">new</span> <span style="color:#f8c555">interceptorsManner</span><span style="color:#cccccc">(</span><span style="color:#cccccc">)</span><span style="color:#cccccc">,</span>response<span style="color:#67cdcc">:</span> <span style="color:#cc99cd">new</span> <span style="color:#f8c555">interceptorsManner</span><span style="color:#cccccc">(</span><span style="color:#cccccc">)</span><span style="color:#cccccc">}</span>axios<span style="color:#cccccc">.</span>prototype<span style="color:#cccccc">.</span><span style="color:#f08d49">request</span> <span style="color:#67cdcc">=</span> <span style="color:#cc99cd">function</span><span style="color:#cccccc">(</span><span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span><span style="color:#cc99cd">var</span> chain <span style="color:#67cdcc">=</span> <span style="color:#cccccc">[</span>dispathReuest<span style="color:#cccccc">,</span> <span style="color:#cc99cd">undefined</span><span style="color:#cccccc">]</span><span style="color:#cc99cd">var</span> promise <span style="color:#67cdcc">=</span> Promise<span style="color:#cccccc">.</span><span style="color:#f08d49">resolve</span><span style="color:#cccccc">(</span>config<span style="color:#cccccc">)</span><span style="color:#cc99cd">this</span><span style="color:#cccccc">.</span>interceptors<span style="color:#cccccc">.</span>request<span style="color:#cccccc">.</span>handlers<span style="color:#cccccc">.</span><span style="color:#f08d49">forEach</span><span style="color:#cccccc">(</span>interceptor <span style="color:#67cdcc">=></span> <span style="color:#cccccc">{</span>chain<span style="color:#cccccc">.</span><span style="color:#f08d49">unshift</span><span style="color:#cccccc">(</span>interceptor<span style="color:#cccccc">.</span>fulfilled<span style="color:#cccccc">,</span> interceptor<span style="color:#cccccc">.</span>injected<span style="color:#cccccc">)</span><span style="color:#cccccc">}</span><span style="color:#cccccc">)</span><span style="color:#cc99cd">this</span><span style="color:#cccccc">.</span>interceptors<span style="color:#cccccc">.</span>response<span style="color:#cccccc">.</span>handlers<span style="color:#cccccc">.</span><span style="color:#f08d49">forEach</span><span style="color:#cccccc">(</span>interceptor <span style="color:#67cdcc">=></span> <span style="color:#cccccc">{</span>chain<span style="color:#cccccc">.</span><span style="color:#f08d49">shift</span><span style="color:#cccccc">(</span>interceptor<span style="color:#cccccc">.</span>fulfilled<span style="color:#cccccc">,</span> interceptor<span style="color:#cccccc">.</span>injected<span style="color:#cccccc">)</span><span style="color:#cccccc">}</span><span style="color:#cccccc">)</span><span style="color:#cc99cd">while</span> <span style="color:#cccccc">(</span>chain<span style="color:#cccccc">.</span>length<span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span>promise <span style="color:#67cdcc">=</span> promise<span style="color:#cccccc">.</span><span style="color:#f08d49">then</span><span style="color:#cccccc">(</span>chain<span style="color:#cccccc">.</span><span style="color:#f08d49">shift</span><span style="color:#cccccc">(</span><span style="color:#cccccc">)</span><span style="color:#cccccc">,</span> chain<span style="color:#cccccc">.</span><span style="color:#f08d49">shift</span><span style="color:#cccccc">(</span><span style="color:#cccccc">)</span><span style="color:#cccccc">)</span><span style="color:#cccccc">}</span><span style="color:#cccccc">}</span>
<span style="color:#cccccc">}</span><span style="color:#cc99cd">function</span> <span style="color:#f08d49">interceptorsManner</span><span style="color:#cccccc">(</span><span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span><span style="color:#cc99cd">this</span><span style="color:#cccccc">.</span>handlers <span style="color:#67cdcc">=</span> <span style="color:#cccccc">[</span><span style="color:#cccccc">]</span>
<span style="color:#cccccc">}</span>interceptorsManner<span style="color:#cccccc">.</span>prototype<span style="color:#cccccc">.</span><span style="color:#f08d49">use</span> <span style="color:#67cdcc">=</span> <span style="color:#cc99cd">function</span><span style="color:#cccccc">(</span>fulfilled<span style="color:#cccccc">,</span> rejected<span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span><span style="color:#cc99cd">this</span><span style="color:#cccccc">.</span>handlers<span style="color:#cccccc">.</span><span style="color:#f08d49">push</span><span style="color:#cccccc">(</span><span style="color:#cccccc">{</span>fulfilled<span style="color:#67cdcc">:</span> fulfilled<span style="color:#cccccc">,</span>rejected<span style="color:#67cdcc">:</span> rejected<span style="color:#cccccc">}</span><span style="color:#cccccc">)</span>
<span style="color:#cccccc">}</span>
</code></span></span></span>
利用职责链组织一个表单验证
需求:有一个表单,需要前后台校验,后台校验
<span style="background-color:#282c34"><span style="color:#2c3e50"><span style="color:#cccccc"><code><span style="color:#999999">// 表单事件绑定->表单前端验证->表单后端验证</span>
<span style="color:#999999">// 思想:把你要做的事情拆分为模块,模块之间只做自己模块的事情</span>input<span style="color:#cccccc">.</span><span style="color:#f08d49">onblur</span> <span style="color:#67cdcc">=</span> <span style="color:#cc99cd">function</span><span style="color:#cccccc">(</span><span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span><span style="color:#cc99cd">var</span> _value <span style="color:#67cdcc">=</span> input<span style="color:#cccccc">.</span>value<span style="color:#cc99cd">var</span> _arr <span style="color:#67cdcc">=</span> <span style="color:#cccccc">[</span>font<span style="color:#cccccc">,</span> middle<span style="color:#cccccc">,</span> back<span style="color:#cccccc">,</span> fontAgain<span style="color:#cccccc">]</span><span style="color:#cc99cd">async</span> <span style="color:#cc99cd">function</span> <span style="color:#f08d49">test</span><span style="color:#cccccc">(</span><span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span><span style="color:#cc99cd">var</span> _result <span style="color:#67cdcc">=</span> _value<span style="color:#cc99cd">while</span> <span style="color:#cccccc">(</span>_arr<span style="color:#cccccc">.</span>length <span style="color:#67cdcc">></span> <span style="color:#f08d49">0</span><span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span>_result <span style="color:#67cdcc">=</span> <span style="color:#cc99cd">await</span> _arr<span style="color:#cccccc">.</span><span style="color:#f08d49">shift</span><span style="color:#cccccc">(</span><span style="color:#cccccc">)</span><span style="color:#cccccc">(</span>_result<span style="color:#cccccc">)</span><span style="color:#cccccc">}</span><span style="color:#cc99cd">return</span> _result<span style="color:#cccccc">}</span><span style="color:#f08d49">test</span><span style="color:#cccccc">(</span><span style="color:#cccccc">)</span><span style="color:#cccccc">.</span><span style="color:#f08d49">then</span><span style="color:#cccccc">(</span>res <span style="color:#67cdcc">=></span> <span style="color:#cccccc">{</span>console<span style="color:#cccccc">.</span><span style="color:#f08d49">log</span><span style="color:#cccccc">(</span>res<span style="color:#cccccc">)</span><span style="color:#cccccc">}</span><span style="color:#cccccc">)</span>
<span style="color:#cccccc">}</span><span style="color:#cc99cd">function</span> <span style="color:#f08d49">font</span><span style="color:#cccccc">(</span>result<span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span><span style="color:#cccccc">}</span><span style="color:#cc99cd">function</span> <span style="color:#f08d49">middle</span><span style="color:#cccccc">(</span>result<span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span><span style="color:#cccccc">}</span><span style="color:#cc99cd">function</span> <span style="color:#f08d49">back</span><span style="color:#cccccc">(</span>result<span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span><span style="color:#cccccc">}</span><span style="color:#cc99cd">function</span> <span style="color:#f08d49">fontAgain</span><span style="color:#cccccc">(</span>result<span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span><span style="color:#cccccc">}</span>
</code></span></span></span>
# 访问者模式示例
不同角色访问数据
需求:假设有一个公司的财务报表,财务关心支出和收入,老板关心盈利
<span style="background-color:#282c34"><span style="color:#2c3e50"><span style="color:#cccccc"><code><span style="color:#cc99cd">function</span> <span style="color:#f08d49">report</span><span style="color:#cccccc">(</span><span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span><span style="color:#cc99cd">this</span><span style="color:#cccccc">.</span>income <span style="color:#67cdcc">=</span> <span style="color:#7ec699">''</span><span style="color:#cc99cd">this</span><span style="color:#cccccc">.</span>cost <span style="color:#67cdcc">=</span> <span style="color:#7ec699">''</span><span style="color:#cc99cd">this</span><span style="color:#cccccc">.</span>profit <span style="color:#67cdcc">=</span> <span style="color:#7ec699">''</span>
<span style="color:#cccccc">}</span><span style="color:#cc99cd">function</span> <span style="color:#f08d49">boss</span><span style="color:#cccccc">(</span><span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span><span style="color:#cccccc">}</span>boss<span style="color:#cccccc">.</span>prototype<span style="color:#cccccc">.</span><span style="color:#f08d49">get</span> <span style="color:#67cdcc">=</span> <span style="color:#cc99cd">function</span><span style="color:#cccccc">(</span>data<span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span><span style="color:#cccccc">}</span><span style="color:#cc99cd">function</span> <span style="color:#f08d49">account</span><span style="color:#cccccc">(</span><span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span><span style="color:#cccccc">}</span>account<span style="color:#cccccc">.</span>prototype<span style="color:#cccccc">.</span><span style="color:#f08d49">get</span> <span style="color:#67cdcc">=</span> <span style="color:#cc99cd">function</span><span style="color:#cccccc">(</span>num1<span style="color:#cccccc">,</span> num2<span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span><span style="color:#cccccc">}</span><span style="color:#cc99cd">function</span> <span style="color:#f08d49">vistor</span><span style="color:#cccccc">(</span>data<span style="color:#cccccc">,</span> man<span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span><span style="color:#cc99cd">var</span> handle <span style="color:#67cdcc">=</span> <span style="color:#cccccc">{</span><span style="color:#f08d49">boss</span><span style="color:#67cdcc">:</span> <span style="color:#cc99cd">function</span><span style="color:#cccccc">(</span>data<span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span>man<span style="color:#cccccc">.</span><span style="color:#f08d49">get</span><span style="color:#cccccc">(</span>data<span style="color:#cccccc">.</span>profit<span style="color:#cccccc">)</span><span style="color:#cccccc">}</span><span style="color:#cccccc">,</span><span style="color:#f08d49">account</span><span style="color:#67cdcc">:</span> <span style="color:#cc99cd">function</span><span style="color:#cccccc">(</span>data<span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span>man<span style="color:#cccccc">.</span><span style="color:#f08d49">get</span><span style="color:#cccccc">(</span>data<span style="color:#cccccc">.</span>income<span style="color:#cccccc">,</span> data<span style="color:#cccccc">.</span>cost<span style="color:#cccccc">)</span><span style="color:#cccccc">}</span><span style="color:#cccccc">}</span>handle<span style="color:#cccccc">[</span>man<span style="color:#cccccc">.</span>constructor<span style="color:#cccccc">.</span>name<span style="color:#cccccc">]</span><span style="color:#cccccc">(</span>data<span style="color:#cccccc">)</span>
<span style="color:#cccccc">}</span><span style="color:#f08d49">vistor</span><span style="color:#cccccc">(</span><span style="color:#cc99cd">new</span> <span style="color:#f8c555">report</span><span style="color:#cccccc">(</span><span style="color:#cccccc">)</span><span style="color:#cccccc">,</span> <span style="color:#cc99cd">new</span> <span style="color:#f8c555">account</span><span style="color:#cccccc">(</span><span style="color:#cccccc">)</span><span style="color:#cccccc">)</span>
<span style="color:#f08d49">vistor</span><span style="color:#cccccc">(</span><span style="color:#cc99cd">new</span> <span style="color:#f8c555">report</span><span style="color:#cccccc">(</span><span style="color:#cccccc">)</span><span style="color:#cccccc">,</span> <span style="color:#cc99cd">new</span> <span style="color:#f8c555">boss</span><span style="color:#cccccc">(</span><span style="color:#cccccc">)</span><span style="color:#cccccc">)</span><span style="color:#999999">// 设计的数据结构操作难以去访问具体的数据结构的时候</span>
</code></span></span></span>
表格操作
需求:一个可以新增,删除的表格
<span style="background-color:#282c34"><span style="color:#2c3e50"><span style="color:#cccccc"><code> <span style="color:#cc99cd">function</span> <span style="color:#f08d49">table</span> <span style="color:#cccccc">(</span><span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span> <span style="color:#cccccc">}</span>table<span style="color:#cccccc">.</span>prototype<span style="color:#cccccc">.</span><span style="color:#f08d49">show</span><span style="color:#67cdcc">=</span><span style="color:#cc99cd">function</span> <span style="color:#cccccc">(</span><span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span><span style="color:#cccccc">}</span>table<span style="color:#cccccc">.</span>prototype<span style="color:#cccccc">.</span><span style="color:#f08d49">delete</span><span style="color:#67cdcc">=</span><span style="color:#cc99cd">function</span> <span style="color:#cccccc">(</span><span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span><span style="color:#f08d49">vistor</span><span style="color:#cccccc">(</span><span style="color:#cc99cd">this</span><span style="color:#cccccc">.</span>tableData<span style="color:#cccccc">,</span><span style="color:#7ec699">'delete'</span><span style="color:#cccccc">,</span>id<span style="color:#cccccc">)</span><span style="color:#cccccc">}</span>table<span style="color:#cccccc">.</span>prototype<span style="color:#cccccc">.</span><span style="color:#f08d49">add</span><span style="color:#67cdcc">=</span><span style="color:#cc99cd">function</span> <span style="color:#cccccc">(</span><span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span><span style="color:#cccccc">}</span><span style="color:#cc99cd">var</span> tableData<span style="color:#67cdcc">=</span><span style="color:#cccccc">[</span><span style="color:#cccccc">{</span>id<span style="color:#67cdcc">:</span><span style="color:#f08d49">1</span><span style="color:#cccccc">,</span>name<span style="color:#67cdcc">:</span><span style="color:#7ec699">'xxx'</span><span style="color:#cccccc">,</span>prize<span style="color:#67cdcc">:</span><span style="color:#7ec699">'xxx'</span><span style="color:#cccccc">}</span><span style="color:#cccccc">]</span><span style="color:#cc99cd">function</span> <span style="color:#f08d49">vistor</span> <span style="color:#cccccc">(</span>table<span style="color:#cccccc">,</span>data<span style="color:#cccccc">,</span>handle<span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span><span style="color:#cc99cd">var</span> handleOb<span style="color:#67cdcc">=</span><span style="color:#cccccc">{</span><span style="color:#f08d49">delete</span><span style="color:#67cdcc">:</span><span style="color:#cc99cd">function</span><span style="color:#cccccc">(</span>id<span style="color:#cccccc">)</span><span style="color:#cccccc">{</span><span style="color:#cccccc">}</span><span style="color:#cccccc">,</span>add<span style="color:#67cdcc">:</span><span style="color:#f08d49">funtion</span><span style="color:#cccccc">(</span>id<span style="color:#cccccc">,</span>name<span style="color:#cccccc">,</span>price<span style="color:#cccccc">)</span><span style="color:#cccccc">{</span><span style="color:#cccccc">}</span><span style="color:#cccccc">}</span><span style="color:#cc99cd">var</span> arg<span style="color:#67cdcc">=</span><span style="color:#f8c555">Array</span><span style="color:#cccccc">.</span>prototype<span style="color:#cccccc">.</span><span style="color:#f08d49">splice</span><span style="color:#cccccc">(</span>arguments<span style="color:#cccccc">)</span><span style="color:#cccccc">;</span>arg<span style="color:#cccccc">.</span><span style="color:#f08d49">splice</span><span style="color:#cccccc">(</span><span style="color:#f08d49">0</span><span style="color:#cccccc">,</span><span style="color:#f08d49">3</span><span style="color:#cccccc">)</span><span style="color:#cccccc">;</span>handleOb<span style="color:#cccccc">[</span>handle<span style="color:#cccccc">]</span><span style="color:#cccccc">.</span><span style="color:#f08d49">apple</span><span style="color:#cccccc">(</span><span style="color:#cc99cd">this</span><span style="color:#cccccc">,</span>arg<span style="color:#cccccc">)</span><span style="color:#cccccc">}</span>
</code></span></span></span>
#5.4 总结
- 观察者模式
适用于不适合直接沟通的模块之间的组织
- 职责链模式
组织同步模块,把要做的事情划分为模块,要做的事情一次传递
- 访问者模式
解耦数据操作与数据结构
#6. 提高代码质量
提高代码质量
- 高质量的代码,方便后续的一切操作
- 方便他人阅读
什么是代码质量
- 代码整洁
- 结构规整,没有漫长的结构
- 阅读好理解
#6.1 优化代码结构
- 策略模式/状态模式
策略/状态模式的目的:优化 if-else 分支
策略/状态模式的应用场景:当代码 if-else 分支过多时
- 外观模式
外观模式的目的:通过为多个复杂的子系统提供一个一致的接口
外观模式的应用场景:当完成一个操作时,需要操作多个子系统,不如提供一个更高级的
#6.2 优化你的代码操作
- 迭代器模式
迭代器者模式的目的:不访问内部的情况下,方便的遍历数据
迭代器模式的应用场景:当我们需要对某个对象进行操作,但是又不能暴露内部
- 备忘录模式
备忘录模式的目的:记录状态,方便回滚
备忘录模式的应用场景:系统状态多样,为了保证状态的回滚方便,记录状态
#6.3 基本结构
#策略模式的基本结构
假设要编写一个计算器,有加减乘除,我们把一层一层的 if 判断,变成下面的形式
<span style="background-color:#282c34"><span style="color:#2c3e50"><span style="color:#cccccc"><code> <span style="color:#cc99cd">function</span> <span style="color:#f08d49">Strategy</span> <span style="color:#cccccc">(</span>type<span style="color:#cccccc">,</span>a<span style="color:#cccccc">,</span>b<span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span><span style="color:#cc99cd">var</span> Strategyer<span style="color:#67cdcc">=</span><span style="color:#cccccc">{</span><span style="color:#f08d49">add</span><span style="color:#67cdcc">:</span><span style="color:#cc99cd">function</span> <span style="color:#cccccc">(</span>a<span style="color:#cccccc">,</span>b<span style="color:#cccccc">)</span><span style="color:#cccccc">{</span><span style="color:#cc99cd">return</span> a<span style="color:#67cdcc">+</span>b<span style="color:#cccccc">}</span><span style="color:#f08d49">minus</span><span style="color:#67cdcc">:</span><span style="color:#cc99cd">function</span><span style="color:#cccccc">(</span>a<span style="color:#cccccc">,</span>b<span style="color:#cccccc">)</span><span style="color:#cccccc">{</span><span style="color:#cc99cd">return</span> a<span style="color:#67cdcc">-</span>b<span style="color:#cccccc">}</span><span style="color:#f08d49">division</span><span style="color:#67cdcc">:</span><span style="color:#cc99cd">function</span> <span style="color:#cccccc">(</span>a<span style="color:#cccccc">,</span>b<span style="color:#cccccc">)</span><span style="color:#cccccc">{</span><span style="color:#cc99cd">return</span> a<span style="color:#67cdcc">/</span>b<span style="color:#cccccc">}</span><span style="color:#cccccc">}</span><span style="color:#cc99cd">return</span> Strategyer<span style="color:#cccccc">[</span>type<span style="color:#cccccc">]</span><span style="color:#cccccc">(</span>a<span style="color:#cccccc">,</span>b<span style="color:#cccccc">)</span><span style="color:#cccccc">}</span>
</code></span></span></span>
# 状态模式的基本结构(加了状态的策略模式)
为了减少 if-else 结构,将判断变成对象内部的一个状态,通过对象内部的状态改变,让其拥有不同的行为
<span style="background-color:#282c34"><span style="color:#2c3e50"><span style="color:#cccccc"><code><span style="color:#cc99cd">function</span> <span style="color:#f08d49">stateFactor</span><span style="color:#cccccc">(</span>state<span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span><span style="color:#cc99cd">var</span> stateObject <span style="color:#67cdcc">=</span> <span style="color:#cccccc">{</span>_status<span style="color:#67cdcc">:</span> <span style="color:#7ec699">''</span><span style="color:#cccccc">,</span>state<span style="color:#67cdcc">:</span> <span style="color:#cccccc">{</span><span style="color:#f08d49">state1</span><span style="color:#67cdcc">:</span> <span style="color:#cc99cd">function</span><span style="color:#cccccc">(</span><span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span><span style="color:#cccccc">}</span><span style="color:#cccccc">,</span><span style="color:#f08d49">state2</span><span style="color:#67cdcc">:</span> <span style="color:#cc99cd">function</span><span style="color:#cccccc">(</span><span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span><span style="color:#cccccc">}</span><span style="color:#cccccc">}</span><span style="color:#cccccc">,</span><span style="color:#f08d49">run</span><span style="color:#67cdcc">:</span> <span style="color:#cc99cd">function</span><span style="color:#cccccc">(</span><span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span><span style="color:#cc99cd">return</span> <span style="color:#cc99cd">this</span><span style="color:#cccccc">.</span>state<span style="color:#cccccc">[</span><span style="color:#cc99cd">this</span><span style="color:#cccccc">.</span>_status<span style="color:#cccccc">]</span><span style="color:#cccccc">}</span><span style="color:#cccccc">}</span>stateObject<span style="color:#cccccc">.</span>_status <span style="color:#67cdcc">=</span> state<span style="color:#cc99cd">return</span> stateObject
<span style="color:#cccccc">}</span>
</code></span></span></span>
# 外观模式的基本结构
我们组织方法模块时可以细化多个接口,但是我们给别人使用时,要合为一个接口就像你可以直接去餐厅去点套餐
<span style="background-color:#282c34"><span style="color:#2c3e50"><span style="color:#cccccc"><code><span style="color:#999999">// 模块1</span>
<span style="color:#cc99cd">function</span> <span style="color:#f08d49">Model1</span><span style="color:#cccccc">(</span><span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span><span style="color:#cccccc">}</span>
<span style="color:#999999">// 模块2</span>
<span style="color:#cc99cd">function</span> <span style="color:#f08d49">Model2</span><span style="color:#cccccc">(</span><span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span><span style="color:#cccccc">}</span>
<span style="color:#999999">// 功能由Model1获取Model2得结果来完成</span><span style="color:#cc99cd">function</span> <span style="color:#f08d49">use</span><span style="color:#cccccc">(</span><span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span><span style="color:#f08d49">Model2</span><span style="color:#cccccc">(</span><span style="color:#f08d49">Model1</span><span style="color:#cccccc">(</span><span style="color:#cccccc">)</span><span style="color:#cccccc">)</span>
<span style="color:#cccccc">}</span>
</code></span></span></span>
# 迭代器模式的基本结构
在不暴露对象内部结构的同时,可以顺序的访问对象内部,可以帮助我们简化循环,简化数据操作
<span style="background-color:#282c34"><span style="color:#2c3e50"><span style="color:#cccccc"><code><span style="color:#cc99cd">function</span> <span style="color:#f08d49">Iterator</span><span style="color:#cccccc">(</span>item<span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span><span style="color:#cc99cd">this</span><span style="color:#cccccc">.</span>item <span style="color:#67cdcc">=</span> item
<span style="color:#cccccc">}</span>
<span style="color:#f8c555">Iterator</span><span style="color:#cccccc">.</span>prototype<span style="color:#cccccc">.</span><span style="color:#f08d49">dealEach</span> <span style="color:#67cdcc">=</span> <span style="color:#cc99cd">function</span><span style="color:#cccccc">(</span>fn<span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span><span style="color:#cc99cd">for</span> <span style="color:#cccccc">(</span><span style="color:#cc99cd">var</span> i <span style="color:#67cdcc">=</span> <span style="color:#f08d49">0</span><span style="color:#cccccc">;</span> i <span style="color:#67cdcc"><</span> <span style="color:#cc99cd">this</span><span style="color:#cccccc">.</span>item<span style="color:#cccccc">.</span>length<span style="color:#cccccc">;</span> i<span style="color:#67cdcc">++</span><span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span><span style="color:#f08d49">fn</span><span style="color:#cccccc">(</span><span style="color:#cc99cd">this</span><span style="color:#cccccc">.</span>item<span style="color:#cccccc">[</span>i<span style="color:#cccccc">]</span><span style="color:#cccccc">,</span> i<span style="color:#cccccc">)</span><span style="color:#cccccc">}</span>
<span style="color:#cccccc">}</span>
</code></span></span></span>
# 备忘录模式的基本结构
记录对象内部的状态,当有需要时回滚到之前的状态或者方便对象使用
<span style="background-color:#282c34"><span style="color:#2c3e50"><span style="color:#cccccc"><code><span style="color:#cc99cd">function</span> <span style="color:#f08d49">Memento</span><span style="color:#cccccc">(</span><span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span><span style="color:#cc99cd">var</span> cache <span style="color:#67cdcc">=</span> <span style="color:#cccccc">{</span><span style="color:#cccccc">}</span><span style="color:#cc99cd">return</span> <span style="color:#cc99cd">function</span><span style="color:#cccccc">(</span>cacheName<span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span><span style="color:#cc99cd">if</span> <span style="color:#cccccc">(</span>cache<span style="color:#cccccc">[</span>cacheName<span style="color:#cccccc">]</span><span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span><span style="color:#999999">// 有缓存的操作</span><span style="color:#cccccc">}</span> <span style="color:#cc99cd">else</span> <span style="color:#cccccc">{</span><span style="color:#999999">// 没有缓存的操作</span><span style="color:#cccccc">}</span><span style="color:#cccccc">}</span>
<span style="color:#cccccc">}</span>
<span style="color:#cc99cd">var</span> MementtoFn <span style="color:#67cdcc">=</span> <span style="color:#f08d49">Memento</span><span style="color:#cccccc">(</span><span style="color:#cccccc">)</span>
<span style="color:#f08d49">MementtoFn</span><span style="color:#cccccc">(</span><span style="color:#7ec699">'xxxcx'</span><span style="color:#cccccc">)</span>
</code></span></span></span>
#6.4 应用示例
# 策略/状态模式的示例
动态的内容
需求:项目有一个动态的内容,根据用户权限的不同显示不同的内容
<span style="background-color:#282c34"><span style="color:#2c3e50"><span style="color:#cccccc"><code><span style="color:#999999">// 没有用策略的模式的情况</span>
<span style="color:#cc99cd">function</span> <span style="color:#f08d49">showPart1</span><span style="color:#cccccc">(</span><span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span>console<span style="color:#cccccc">.</span><span style="color:#f08d49">log</span><span style="color:#cccccc">(</span><span style="color:#f08d49">1</span><span style="color:#cccccc">)</span>
<span style="color:#cccccc">}</span>
<span style="color:#cc99cd">function</span> <span style="color:#f08d49">showPart2</span><span style="color:#cccccc">(</span><span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span>console<span style="color:#cccccc">.</span><span style="color:#f08d49">log</span><span style="color:#cccccc">(</span><span style="color:#f08d49">2</span><span style="color:#cccccc">)</span>
<span style="color:#cccccc">}</span>
<span style="color:#cc99cd">function</span> <span style="color:#f08d49">showPart3</span><span style="color:#cccccc">(</span><span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span>console<span style="color:#cccccc">.</span><span style="color:#f08d49">log</span><span style="color:#cccccc">(</span><span style="color:#f08d49">3</span><span style="color:#cccccc">)</span>
<span style="color:#cccccc">}</span>
axios<span style="color:#cccccc">.</span><span style="color:#f08d49">get</span><span style="color:#cccccc">(</span><span style="color:#7ec699">'xxx'</span><span style="color:#cccccc">)</span><span style="color:#cccccc">.</span><span style="color:#f08d49">then</span><span style="color:#cccccc">(</span>res <span style="color:#67cdcc">=></span> <span style="color:#cccccc">{</span><span style="color:#cc99cd">if</span> <span style="color:#cccccc">(</span>res <span style="color:#67cdcc">==</span> <span style="color:#7ec699">'boss'</span><span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span><span style="color:#f08d49">showPart1</span><span style="color:#cccccc">(</span><span style="color:#cccccc">)</span><span style="color:#f08d49">showPart2</span><span style="color:#cccccc">(</span><span style="color:#cccccc">)</span><span style="color:#f08d49">showPart3</span><span style="color:#cccccc">(</span><span style="color:#cccccc">)</span><span style="color:#cccccc">}</span> <span style="color:#cc99cd">else</span> <span style="color:#cc99cd">if</span> <span style="color:#cccccc">(</span>res <span style="color:#67cdcc">==</span> <span style="color:#7ec699">'manner'</span><span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span><span style="color:#f08d49">showPart1</span><span style="color:#cccccc">(</span><span style="color:#cccccc">)</span><span style="color:#f08d49">showPart2</span><span style="color:#cccccc">(</span><span style="color:#cccccc">)</span><span style="color:#cccccc">}</span> <span style="color:#cc99cd">else</span> <span style="color:#cc99cd">if</span> <span style="color:#cccccc">(</span>res <span style="color:#67cdcc">==</span> <span style="color:#7ec699">'staff'</span><span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span><span style="color:#f08d49">showPart3</span><span style="color:#cccccc">(</span><span style="color:#cccccc">)</span><span style="color:#cccccc">}</span>
<span style="color:#cccccc">}</span><span style="color:#cccccc">)</span><span style="color:#999999">// 用策略模式的情况</span>
<span style="color:#cc99cd">function</span> <span style="color:#f08d49">showControl</span><span style="color:#cccccc">(</span><span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span><span style="color:#cc99cd">this</span><span style="color:#cccccc">.</span>status <span style="color:#67cdcc">=</span> <span style="color:#7ec699">''</span><span style="color:#cc99cd">this</span><span style="color:#cccccc">.</span>power <span style="color:#67cdcc">=</span> <span style="color:#cccccc">{</span><span style="color:#f08d49">boss</span><span style="color:#67cdcc">:</span> <span style="color:#cc99cd">function</span><span style="color:#cccccc">(</span><span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span><span style="color:#f08d49">showPart1</span><span style="color:#cccccc">(</span><span style="color:#cccccc">)</span><span style="color:#f08d49">showPart2</span><span style="color:#cccccc">(</span><span style="color:#cccccc">)</span><span style="color:#f08d49">showPart3</span><span style="color:#cccccc">(</span><span style="color:#cccccc">)</span><span style="color:#cccccc">}</span><span style="color:#cccccc">,</span><span style="color:#f08d49">manner</span><span style="color:#67cdcc">:</span> <span style="color:#cc99cd">function</span><span style="color:#cccccc">(</span><span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span><span style="color:#f08d49">showPart1</span><span style="color:#cccccc">(</span><span style="color:#cccccc">)</span><span style="color:#f08d49">showPart2</span><span style="color:#cccccc">(</span><span style="color:#cccccc">)</span><span style="color:#cccccc">}</span><span style="color:#cccccc">,</span><span style="color:#f08d49">staff</span><span style="color:#67cdcc">:</span> <span style="color:#cc99cd">function</span><span style="color:#cccccc">(</span><span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span><span style="color:#f08d49">showPart3</span><span style="color:#cccccc">(</span><span style="color:#cccccc">)</span><span style="color:#cccccc">}</span><span style="color:#cccccc">}</span>
<span style="color:#cccccc">}</span>
showControl<span style="color:#cccccc">.</span>prototype<span style="color:#cccccc">.</span><span style="color:#f08d49">show</span> <span style="color:#67cdcc">=</span> <span style="color:#cc99cd">function</span><span style="color:#cccccc">(</span><span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span><span style="color:#cc99cd">var</span> self <span style="color:#67cdcc">=</span> <span style="color:#cc99cd">this</span>axios<span style="color:#cccccc">.</span><span style="color:#f08d49">get</span><span style="color:#cccccc">(</span><span style="color:#7ec699">'xxx'</span><span style="color:#cccccc">)</span><span style="color:#cccccc">.</span><span style="color:#f08d49">then</span><span style="color:#cccccc">(</span>res <span style="color:#67cdcc">=></span> <span style="color:#cccccc">{</span>self<span style="color:#cccccc">.</span>status <span style="color:#67cdcc">=</span> resself<span style="color:#cccccc">.</span>power<span style="color:#cccccc">[</span>self<span style="color:#cccccc">.</span>status<span style="color:#cccccc">]</span><span style="color:#cccccc">(</span><span style="color:#cccccc">)</span><span style="color:#cccccc">}</span><span style="color:#cccccc">)</span>
<span style="color:#cccccc">}</span>
<span style="color:#cc99cd">new</span> <span style="color:#f8c555">showControl</span><span style="color:#cccccc">(</span><span style="color:#cccccc">)</span><span style="color:#cccccc">.</span><span style="color:#f08d49">show</span><span style="color:#cccccc">(</span><span style="color:#cccccc">)</span>
</code></span></span></span>
复合运动
需求:有一个小球,可以控制它左右移动,或则左前,右前等方式移动
<span style="background-color:#282c34"><span style="color:#2c3e50"><span style="color:#cccccc"><code><span style="color:#cc99cd">function</span> <span style="color:#f08d49">moveLeft</span><span style="color:#cccccc">(</span><span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span>console<span style="color:#cccccc">.</span><span style="color:#f08d49">log</span><span style="color:#cccccc">(</span><span style="color:#7ec699">'left'</span><span style="color:#cccccc">)</span>
<span style="color:#cccccc">}</span>
<span style="color:#cc99cd">function</span> <span style="color:#f08d49">moveRight</span><span style="color:#cccccc">(</span><span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span>console<span style="color:#cccccc">.</span><span style="color:#f08d49">log</span><span style="color:#cccccc">(</span><span style="color:#7ec699">'RigmoveRight'</span><span style="color:#cccccc">)</span>
<span style="color:#cccccc">}</span>
<span style="color:#cc99cd">function</span> <span style="color:#f08d49">moveTop</span><span style="color:#cccccc">(</span><span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span>console<span style="color:#cccccc">.</span><span style="color:#f08d49">log</span><span style="color:#cccccc">(</span><span style="color:#7ec699">'Top'</span><span style="color:#cccccc">)</span>
<span style="color:#cccccc">}</span>
<span style="color:#cc99cd">function</span> <span style="color:#f08d49">moveBottom</span><span style="color:#cccccc">(</span><span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span>console<span style="color:#cccccc">.</span><span style="color:#f08d49">log</span><span style="color:#cccccc">(</span><span style="color:#7ec699">'bomoveBottom'</span><span style="color:#cccccc">)</span>
<span style="color:#cccccc">}</span><span style="color:#999999">// 没有用状态模式的情况</span>
<span style="color:#cc99cd">function</span> <span style="color:#f08d49">mover</span><span style="color:#cccccc">(</span><span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span><span style="color:#cc99cd">if</span> <span style="color:#cccccc">(</span>arguments<span style="color:#cccccc">.</span>length <span style="color:#67cdcc">==</span> <span style="color:#f08d49">1</span><span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span><span style="color:#cc99cd">if</span> <span style="color:#cccccc">(</span>arguments<span style="color:#cccccc">[</span><span style="color:#f08d49">0</span><span style="color:#cccccc">]</span> <span style="color:#67cdcc">==</span> <span style="color:#7ec699">'left'</span><span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span><span style="color:#f08d49">moveLeft</span><span style="color:#cccccc">(</span><span style="color:#cccccc">)</span><span style="color:#cccccc">}</span> <span style="color:#cc99cd">else</span> <span style="color:#cc99cd">if</span> <span style="color:#cccccc">(</span>arguments<span style="color:#cccccc">[</span><span style="color:#f08d49">0</span><span style="color:#cccccc">]</span> <span style="color:#67cdcc">==</span> <span style="color:#7ec699">'right'</span><span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span><span style="color:#f08d49">moveRight</span><span style="color:#cccccc">(</span><span style="color:#cccccc">)</span><span style="color:#cccccc">}</span> <span style="color:#cc99cd">else</span> <span style="color:#cc99cd">if</span> <span style="color:#cccccc">(</span>arguments<span style="color:#cccccc">[</span><span style="color:#f08d49">0</span><span style="color:#cccccc">]</span> <span style="color:#67cdcc">==</span> <span style="color:#7ec699">'top'</span><span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span><span style="color:#f08d49">moveTop</span><span style="color:#cccccc">(</span><span style="color:#cccccc">)</span><span style="color:#cccccc">}</span> <span style="color:#cc99cd">else</span> <span style="color:#cc99cd">if</span> <span style="color:#cccccc">(</span>arguments<span style="color:#cccccc">[</span><span style="color:#f08d49">0</span><span style="color:#cccccc">]</span> <span style="color:#67cdcc">==</span> <span style="color:#7ec699">'bottom'</span><span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span><span style="color:#f08d49">moveBottom</span><span style="color:#cccccc">(</span><span style="color:#cccccc">)</span><span style="color:#cccccc">}</span><span style="color:#cccccc">}</span> <span style="color:#cc99cd">else</span> <span style="color:#cccccc">{</span><span style="color:#cc99cd">if</span> <span style="color:#cccccc">(</span>arguments<span style="color:#cccccc">[</span><span style="color:#f08d49">0</span><span style="color:#cccccc">]</span> <span style="color:#67cdcc">==</span> <span style="color:#7ec699">'left'</span> <span style="color:#67cdcc">&&</span> arguments<span style="color:#cccccc">[</span><span style="color:#f08d49">1</span><span style="color:#cccccc">]</span> <span style="color:#67cdcc">==</span> <span style="color:#7ec699">'top'</span><span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span><span style="color:#f08d49">moveLeft</span><span style="color:#cccccc">(</span><span style="color:#cccccc">)</span><span style="color:#f08d49">moveTop</span><span style="color:#cccccc">(</span><span style="color:#cccccc">)</span><span style="color:#cccccc">}</span> <span style="color:#cc99cd">else</span> <span style="color:#cc99cd">if</span> <span style="color:#cccccc">(</span>arguments<span style="color:#cccccc">[</span><span style="color:#f08d49">0</span><span style="color:#cccccc">]</span> <span style="color:#67cdcc">==</span> <span style="color:#7ec699">'right'</span> <span style="color:#67cdcc">&&</span> arguments<span style="color:#cccccc">[</span><span style="color:#f08d49">1</span><span style="color:#cccccc">]</span> <span style="color:#67cdcc">==</span> <span style="color:#7ec699">'bottom'</span><span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span><span style="color:#f08d49">moveRight</span><span style="color:#cccccc">(</span><span style="color:#cccccc">)</span><span style="color:#f08d49">moveBottom</span><span style="color:#cccccc">(</span><span style="color:#cccccc">)</span><span style="color:#cccccc">}</span><span style="color:#cccccc">}</span>
<span style="color:#cccccc">}</span><span style="color:#999999">// 用状态模式的情况</span>
<span style="color:#cc99cd">function</span> <span style="color:#f08d49">mover</span><span style="color:#cccccc">(</span><span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span><span style="color:#cc99cd">this</span><span style="color:#cccccc">.</span>status <span style="color:#67cdcc">=</span> <span style="color:#cccccc">[</span><span style="color:#cccccc">]</span><span style="color:#cc99cd">this</span><span style="color:#cccccc">.</span>actionHandle <span style="color:#67cdcc">=</span> <span style="color:#cccccc">{</span>left<span style="color:#67cdcc">:</span> moveLeft<span style="color:#cccccc">,</span>right<span style="color:#67cdcc">:</span> moveRight<span style="color:#cccccc">,</span>top<span style="color:#67cdcc">:</span> moveTop<span style="color:#cccccc">,</span>bottom<span style="color:#67cdcc">:</span> moveBottom<span style="color:#cccccc">}</span>
<span style="color:#cccccc">}</span>
mover<span style="color:#cccccc">.</span>prototype<span style="color:#cccccc">.</span><span style="color:#f08d49">run</span> <span style="color:#67cdcc">=</span> <span style="color:#cc99cd">function</span><span style="color:#cccccc">(</span><span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span><span style="color:#cc99cd">this</span><span style="color:#cccccc">.</span>status <span style="color:#67cdcc">=</span> <span style="color:#f8c555">Array</span><span style="color:#cccccc">.</span>prototype<span style="color:#cccccc">.</span><span style="color:#f08d49">slice</span><span style="color:#cccccc">.</span><span style="color:#f08d49">call</span><span style="color:#cccccc">(</span>arguments<span style="color:#cccccc">)</span><span style="color:#cc99cd">this</span><span style="color:#cccccc">.</span>status<span style="color:#cccccc">.</span><span style="color:#f08d49">forEach</span><span style="color:#cccccc">(</span>action <span style="color:#67cdcc">=></span> <span style="color:#cccccc">{</span><span style="color:#cc99cd">this</span><span style="color:#cccccc">.</span>actionHandle<span style="color:#cccccc">[</span>action<span style="color:#cccccc">]</span><span style="color:#cccccc">(</span><span style="color:#cccccc">)</span><span style="color:#cccccc">}</span><span style="color:#cccccc">)</span>
<span style="color:#cccccc">}</span>
<span style="color:#cc99cd">new</span> <span style="color:#f8c555">mover</span><span style="color:#cccccc">(</span><span style="color:#cccccc">)</span><span style="color:#cccccc">.</span><span style="color:#f08d49">run</span><span style="color:#cccccc">(</span><span style="color:#7ec699">'left'</span><span style="color:#cccccc">,</span> <span style="color:#7ec699">'right'</span><span style="color:#cccccc">)</span>
</code></span></span></span>
# 外观模式的示例
插件封装的规律
需求:插件基本都会给最终使用提供一个高级接口
<span style="background-color:#282c34"><span style="color:#2c3e50"><span style="color:#cccccc"><code><span style="color:#999999">// 划分功能,给使用者一个统一的接口</span>
<span style="color:#cc99cd">function</span> <span style="color:#f08d49">tab</span><span style="color:#cccccc">(</span><span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span><span style="color:#cc99cd">this</span><span style="color:#cccccc">.</span>dom <span style="color:#67cdcc">=</span> <span style="color:#cc99cd">null</span>
<span style="color:#cccccc">}</span>
tab<span style="color:#cccccc">.</span>prototype<span style="color:#cccccc">.</span><span style="color:#f08d49">initHTML</span> <span style="color:#67cdcc">=</span> <span style="color:#cc99cd">function</span><span style="color:#cccccc">(</span><span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span><span style="color:#cccccc">}</span>
tab<span style="color:#cccccc">.</span>prototype<span style="color:#cccccc">.</span><span style="color:#f08d49">changeTab</span> <span style="color:#67cdcc">=</span> <span style="color:#cc99cd">function</span><span style="color:#cccccc">(</span><span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span><span style="color:#cccccc">}</span>
tab<span style="color:#cccccc">.</span>prototype<span style="color:#cccccc">.</span><span style="color:#f08d49">eventBind</span> <span style="color:#67cdcc">=</span> <span style="color:#cc99cd">function</span><span style="color:#cccccc">(</span><span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span><span style="color:#cc99cd">var</span> self <span style="color:#67cdcc">=</span> <span style="color:#cc99cd">this</span><span style="color:#cc99cd">this</span><span style="color:#cccccc">.</span>dom<span style="color:#cccccc">.</span><span style="color:#f08d49">onclick</span> <span style="color:#67cdcc">=</span> <span style="color:#cc99cd">function</span><span style="color:#cccccc">(</span><span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span>self<span style="color:#cccccc">.</span><span style="color:#f08d49">changeTab</span><span style="color:#cccccc">(</span><span style="color:#cccccc">)</span><span style="color:#cccccc">}</span>
<span style="color:#cccccc">}</span>
tab<span style="color:#cccccc">.</span>prototype<span style="color:#cccccc">.</span><span style="color:#f08d49">init</span> <span style="color:#67cdcc">=</span> <span style="color:#cc99cd">function</span><span style="color:#cccccc">(</span>config<span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span><span style="color:#cc99cd">this</span><span style="color:#cccccc">.</span><span style="color:#f08d49">initHTML</span><span style="color:#cccccc">(</span>config<span style="color:#cccccc">)</span><span style="color:#cc99cd">this</span><span style="color:#cccccc">.</span><span style="color:#f08d49">eventBind</span><span style="color:#cccccc">(</span><span style="color:#cccccc">)</span>
<span style="color:#cccccc">}</span>
</code></span></span></span>
封装成方法的思想
需求:在兼容时代,我们会常常需要检测能力,不妨作为一个统一接口
<span style="background-color:#282c34"><span style="color:#2c3e50"><span style="color:#cccccc"><code><span style="color:#999999">//dom支持检测</span>
<span style="color:#cc99cd">function</span> <span style="color:#f08d49">addEvent</span><span style="color:#cccccc">(</span>dom<span style="color:#cccccc">,</span> type<span style="color:#cccccc">,</span> fn<span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span><span style="color:#cc99cd">if</span> <span style="color:#cccccc">(</span>dom<span style="color:#cccccc">.</span>addEventListener<span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span>dom<span style="color:#cccccc">.</span><span style="color:#f08d49">addEventListener</span><span style="color:#cccccc">(</span>type<span style="color:#cccccc">,</span> fn<span style="color:#cccccc">,</span> <span style="color:#f08d49">false</span><span style="color:#cccccc">)</span><span style="color:#cccccc">}</span> <span style="color:#cc99cd">else</span> <span style="color:#cc99cd">if</span> <span style="color:#cccccc">(</span>dom<span style="color:#cccccc">.</span>attachEvent<span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span>dom<span style="color:#cccccc">.</span><span style="color:#f08d49">attachEvent</span><span style="color:#cccccc">(</span><span style="color:#7ec699">'on'</span> <span style="color:#67cdcc">+</span> type<span style="color:#cccccc">,</span> fn<span style="color:#cccccc">)</span><span style="color:#cccccc">}</span> <span style="color:#cc99cd">else</span> <span style="color:#cccccc">{</span>dom<span style="color:#cccccc">[</span><span style="color:#7ec699">'on'</span> <span style="color:#67cdcc">+</span> type<span style="color:#cccccc">]</span> <span style="color:#67cdcc">=</span> fn<span style="color:#cccccc">}</span>
<span style="color:#cccccc">}</span>
</code></span></span></span>
# 迭代器模式的示例
构建一个自己的 forEach
需求:forEach 方法其实是一个典型的迭代器方法
<span style="background-color:#282c34"><span style="color:#2c3e50"><span style="color:#cccccc"><code><span style="color:#999999">// 对数组和对象进行迭代</span>
<span style="color:#999999">//forEach</span>
<span style="color:#cc99cd">function</span> <span style="color:#f08d49">Iterator</span><span style="color:#cccccc">(</span>data<span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span><span style="color:#cc99cd">this</span><span style="color:#cccccc">.</span>data <span style="color:#67cdcc">=</span> data
<span style="color:#cccccc">}</span>
<span style="color:#f8c555">Iterator</span><span style="color:#cccccc">.</span>prototype<span style="color:#cccccc">.</span><span style="color:#f08d49">dealEach</span> <span style="color:#67cdcc">=</span> <span style="color:#cc99cd">function</span><span style="color:#cccccc">(</span>fn<span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span><span style="color:#cc99cd">if</span> <span style="color:#cccccc">(</span><span style="color:#cc99cd">this</span><span style="color:#cccccc">.</span>data <span style="color:#cc99cd">instanceof</span> <span style="color:#f8c555">Array</span><span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span><span style="color:#cc99cd">for</span> <span style="color:#cccccc">(</span><span style="color:#cc99cd">var</span> i <span style="color:#67cdcc">=</span> <span style="color:#f08d49">0</span><span style="color:#cccccc">;</span> i <span style="color:#67cdcc"><</span> <span style="color:#cc99cd">this</span><span style="color:#cccccc">.</span>data<span style="color:#cccccc">.</span>length<span style="color:#cccccc">;</span> i<span style="color:#67cdcc">++</span><span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span><span style="color:#f08d49">fn</span><span style="color:#cccccc">(</span><span style="color:#cc99cd">this</span><span style="color:#cccccc">.</span>data<span style="color:#cccccc">[</span>i<span style="color:#cccccc">]</span><span style="color:#cccccc">,</span> i<span style="color:#cccccc">)</span><span style="color:#cccccc">}</span><span style="color:#cccccc">}</span> <span style="color:#cc99cd">else</span> <span style="color:#cccccc">{</span><span style="color:#cc99cd">for</span> <span style="color:#cccccc">(</span><span style="color:#cc99cd">var</span> item <span style="color:#cc99cd">in</span> <span style="color:#cc99cd">this</span><span style="color:#cccccc">.</span>data<span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span><span style="color:#f08d49">fn</span><span style="color:#cccccc">(</span><span style="color:#cc99cd">this</span><span style="color:#cccccc">.</span>data<span style="color:#cccccc">[</span>item<span style="color:#cccccc">]</span><span style="color:#cccccc">,</span> item<span style="color:#cccccc">)</span><span style="color:#cccccc">}</span><span style="color:#cccccc">}</span>
<span style="color:#cccccc">}</span>
</code></span></span></span>
给你的项目数据添加迭代器
需求:项目经常对于后端数据进行遍历操作,不如封装一个迭代器,遍历的更方便
<span style="background-color:#282c34"><span style="color:#2c3e50"><span style="color:#cccccc"><code><span style="color:#999999">//数据迭代器</span>
<span style="color:#cc99cd">var</span> data <span style="color:#67cdcc">=</span> <span style="color:#cccccc">[</span><span style="color:#cccccc">{</span> num<span style="color:#67cdcc">:</span> <span style="color:#f08d49">1</span> <span style="color:#cccccc">}</span><span style="color:#cccccc">,</span> <span style="color:#cccccc">{</span> num<span style="color:#67cdcc">:</span> <span style="color:#f08d49">2</span> <span style="color:#cccccc">}</span><span style="color:#cccccc">,</span> <span style="color:#cccccc">{</span> num<span style="color:#67cdcc">:</span> <span style="color:#f08d49">3</span> <span style="color:#cccccc">}</span><span style="color:#cccccc">]</span>
<span style="color:#cc99cd">function</span> <span style="color:#f08d49">i</span><span style="color:#cccccc">(</span>data<span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span><span style="color:#cc99cd">function</span> <span style="color:#f08d49">Iterator</span><span style="color:#cccccc">(</span>data<span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span><span style="color:#cc99cd">this</span><span style="color:#cccccc">.</span>data <span style="color:#67cdcc">=</span> data<span style="color:#cccccc">}</span><span style="color:#f8c555">Iterator</span><span style="color:#cccccc">.</span>prototype<span style="color:#cccccc">.</span><span style="color:#f08d49">getHasSomenum</span> <span style="color:#67cdcc">=</span> <span style="color:#cc99cd">function</span><span style="color:#cccccc">(</span>handler<span style="color:#cccccc">,</span> num<span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span><span style="color:#cc99cd">var</span> _arr <span style="color:#67cdcc">=</span> <span style="color:#cccccc">[</span><span style="color:#cccccc">]</span><span style="color:#cc99cd">var</span> handleFn<span style="color:#cc99cd">if</span> <span style="color:#cccccc">(</span><span style="color:#cc99cd">typeof</span> handler <span style="color:#67cdcc">==</span> <span style="color:#7ec699">'function'</span><span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span>handleFn <span style="color:#67cdcc">=</span> handler<span style="color:#cccccc">}</span> <span style="color:#cc99cd">else</span> <span style="color:#cccccc">{</span><span style="color:#f08d49">handleFn</span> <span style="color:#67cdcc">=</span> <span style="color:#cc99cd">function</span><span style="color:#cccccc">(</span>item<span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span><span style="color:#cc99cd">if</span> <span style="color:#cccccc">(</span>item<span style="color:#cccccc">[</span>handler<span style="color:#cccccc">]</span> <span style="color:#67cdcc">==</span> num<span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span><span style="color:#cc99cd">return</span> item<span style="color:#cccccc">}</span><span style="color:#cccccc">}</span><span style="color:#cccccc">}</span><span style="color:#cc99cd">for</span> <span style="color:#cccccc">(</span><span style="color:#cc99cd">var</span> i <span style="color:#67cdcc">=</span> <span style="color:#f08d49">0</span><span style="color:#cccccc">;</span> i <span style="color:#67cdcc"><</span> <span style="color:#cc99cd">this</span><span style="color:#cccccc">.</span>data<span style="color:#cccccc">.</span>length<span style="color:#cccccc">;</span> i<span style="color:#67cdcc">++</span><span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span><span style="color:#cc99cd">var</span> _result <span style="color:#67cdcc">=</span> <span style="color:#f08d49">handleFn</span><span style="color:#cccccc">.</span><span style="color:#f08d49">call</span><span style="color:#cccccc">(</span><span style="color:#cc99cd">this</span><span style="color:#cccccc">,</span> <span style="color:#cc99cd">this</span><span style="color:#cccccc">.</span>data<span style="color:#cccccc">[</span>i<span style="color:#cccccc">]</span><span style="color:#cccccc">)</span><span style="color:#cc99cd">if</span> <span style="color:#cccccc">(</span>_result<span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span>_arr<span style="color:#cccccc">.</span><span style="color:#f08d49">push</span><span style="color:#cccccc">(</span>_result<span style="color:#cccccc">)</span><span style="color:#cccccc">}</span><span style="color:#cccccc">}</span><span style="color:#cc99cd">return</span> _arr<span style="color:#cccccc">}</span><span style="color:#cc99cd">return</span> <span style="color:#cc99cd">new</span> <span style="color:#f8c555">Iterator</span><span style="color:#cccccc">(</span>data<span style="color:#cccccc">)</span>
<span style="color:#cccccc">}</span>
<span style="color:#f08d49">i</span><span style="color:#cccccc">(</span>data<span style="color:#cccccc">)</span><span style="color:#cccccc">.</span><span style="color:#f08d49">getHasSomenum</span><span style="color:#cccccc">(</span><span style="color:#7ec699">'num'</span><span style="color:#cccccc">,</span> <span style="color:#f08d49">1</span><span style="color:#cccccc">)</span>
<span style="color:#999999">// 自定义的筛选方法</span>
<span style="color:#f08d49">i</span><span style="color:#cccccc">(</span>data<span style="color:#cccccc">)</span><span style="color:#cccccc">.</span><span style="color:#f08d49">getHasSomenum</span><span style="color:#cccccc">(</span><span style="color:#cc99cd">function</span><span style="color:#cccccc">(</span>item<span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span><span style="color:#cc99cd">if</span> <span style="color:#cccccc">(</span>item<span style="color:#cccccc">.</span>num <span style="color:#67cdcc">-</span> <span style="color:#f08d49">1</span> <span style="color:#67cdcc">==</span> <span style="color:#f08d49">2</span><span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span><span style="color:#cc99cd">return</span> item<span style="color:#cccccc">}</span>
<span style="color:#cccccc">}</span><span style="color:#cccccc">)</span>
</code></span></span></span>
#备忘录模式的示例
文章页的缓存
需求:项目有一个文章页需求,现在进行优化,如果上一篇已经读取过了,则不进行请求,否则请求文章数据
<span style="background-color:#282c34"><span style="color:#2c3e50"><span style="color:#cccccc"><code><span style="color:#999999">//缓存</span>
<span style="color:#cc99cd">function</span> <span style="color:#f08d49">pager</span><span style="color:#cccccc">(</span><span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span><span style="color:#cc99cd">var</span> cache <span style="color:#67cdcc">=</span> <span style="color:#cccccc">{</span><span style="color:#cccccc">}</span><span style="color:#cc99cd">return</span> <span style="color:#cc99cd">function</span><span style="color:#cccccc">(</span>pageName<span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span><span style="color:#cc99cd">if</span> <span style="color:#cccccc">(</span>cache<span style="color:#cccccc">[</span>pageName<span style="color:#cccccc">]</span><span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span><span style="color:#cc99cd">return</span> cache<span style="color:#cccccc">[</span>pageName<span style="color:#cccccc">]</span><span style="color:#cccccc">}</span> <span style="color:#cc99cd">else</span> <span style="color:#cccccc">{</span>axios<span style="color:#cccccc">.</span><span style="color:#f08d49">get</span><span style="color:#cccccc">(</span>pageName<span style="color:#cccccc">)</span><span style="color:#cccccc">.</span><span style="color:#f08d49">then</span><span style="color:#cccccc">(</span>res <span style="color:#67cdcc">=></span> <span style="color:#cccccc">{</span>cache<span style="color:#cccccc">[</span>pageName<span style="color:#cccccc">]</span> <span style="color:#67cdcc">=</span> res<span style="color:#cccccc">}</span><span style="color:#cccccc">)</span><span style="color:#cccccc">}</span><span style="color:#cccccc">}</span>
<span style="color:#cccccc">}</span>
<span style="color:#cc99cd">var</span> getpage <span style="color:#67cdcc">=</span> <span style="color:#f08d49">pager</span><span style="color:#cccccc">(</span><span style="color:#cccccc">)</span>
<span style="color:#f08d49">getpage</span><span style="color:#cccccc">(</span><span style="color:#7ec699">'pageone'</span><span style="color:#cccccc">)</span>
</code></span></span></span>
前进后退功能
需求:开发一个可移动的 div,拥有前进后退功能能回滚到之前的位置
<span style="background-color:#282c34"><span style="color:#2c3e50"><span style="color:#cccccc"><code><span style="color:#999999">//前进后退</span>
<span style="color:#cc99cd">function</span> <span style="color:#f08d49">moveDiv</span><span style="color:#cccccc">(</span><span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span><span style="color:#cc99cd">this</span><span style="color:#cccccc">.</span>stateList <span style="color:#67cdcc">=</span> <span style="color:#cccccc">[</span><span style="color:#cccccc">]</span> <span style="color:#999999">// 缓存之前的状态</span><span style="color:#cc99cd">this</span><span style="color:#cccccc">.</span>nowState <span style="color:#67cdcc">=</span> <span style="color:#f08d49">0</span> <span style="color:#999999">// 状态指针,指向当前状态在哪个</span>
<span style="color:#cccccc">}</span>
<span style="color:#999999">/*** @param {string} type 往哪个方向移动* @param {Number} num 移动多远*/</span>
moveDiv<span style="color:#cccccc">.</span>prototype<span style="color:#cccccc">.</span><span style="color:#f08d49">move</span> <span style="color:#67cdcc">=</span> <span style="color:#cc99cd">function</span><span style="color:#cccccc">(</span>type<span style="color:#cccccc">,</span> num<span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span><span style="color:#f08d49">changeDiv</span><span style="color:#cccccc">(</span>type<span style="color:#cccccc">,</span> num<span style="color:#cccccc">)</span> <span style="color:#999999">//假设移动位置的函数</span><span style="color:#cc99cd">this</span><span style="color:#cccccc">.</span>stateList<span style="color:#cccccc">.</span><span style="color:#f08d49">push</span><span style="color:#cccccc">(</span><span style="color:#cccccc">{</span>type<span style="color:#67cdcc">:</span> type<span style="color:#cccccc">,</span>num<span style="color:#67cdcc">:</span> num<span style="color:#cccccc">}</span><span style="color:#cccccc">)</span> <span style="color:#999999">// 添加状态</span><span style="color:#cc99cd">this</span><span style="color:#cccccc">.</span>nowState <span style="color:#67cdcc">=</span> <span style="color:#cc99cd">this</span><span style="color:#cccccc">.</span>stateList<span style="color:#cccccc">.</span>length <span style="color:#67cdcc">-</span> <span style="color:#f08d49">1</span> <span style="color:#999999">// 设置当前指针</span>
<span style="color:#cccccc">}</span>
moveDiv<span style="color:#cccccc">.</span>prototype<span style="color:#cccccc">.</span><span style="color:#f08d49">go</span> <span style="color:#67cdcc">=</span> <span style="color:#cc99cd">function</span><span style="color:#cccccc">(</span><span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span><span style="color:#999999">//前进</span><span style="color:#cc99cd">var</span> _state<span style="color:#cc99cd">if</span> <span style="color:#cccccc">(</span><span style="color:#cc99cd">this</span><span style="color:#cccccc">.</span>nowState <span style="color:#67cdcc"><</span> <span style="color:#cc99cd">this</span><span style="color:#cccccc">.</span>stateList<span style="color:#cccccc">.</span>length <span style="color:#67cdcc">-</span> <span style="color:#f08d49">1</span><span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span><span style="color:#999999">//当前指针小于数组最后一位,说明能前进</span><span style="color:#cc99cd">this</span><span style="color:#cccccc">.</span>nowState<span style="color:#67cdcc">++</span>_state <span style="color:#67cdcc">=</span> <span style="color:#cc99cd">this</span><span style="color:#cccccc">.</span>stateList<span style="color:#cccccc">[</span><span style="color:#cc99cd">this</span><span style="color:#cccccc">.</span>nowState<span style="color:#cccccc">]</span><span style="color:#f08d49">changeDiv</span><span style="color:#cccccc">(</span>_state<span style="color:#cccccc">.</span>type<span style="color:#cccccc">,</span> _state<span style="color:#cccccc">.</span>num<span style="color:#cccccc">)</span><span style="color:#cccccc">}</span>
<span style="color:#cccccc">}</span>
moveDiv<span style="color:#cccccc">.</span>prototype<span style="color:#cccccc">.</span><span style="color:#f08d49">back</span> <span style="color:#67cdcc">=</span> <span style="color:#cc99cd">function</span><span style="color:#cccccc">(</span><span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span><span style="color:#999999">//后退</span><span style="color:#cc99cd">var</span> _state<span style="color:#cc99cd">if</span> <span style="color:#cccccc">(</span><span style="color:#cc99cd">this</span><span style="color:#cccccc">.</span>nowState <span style="color:#67cdcc">>=</span> <span style="color:#f08d49">0</span><span style="color:#cccccc">)</span> <span style="color:#cccccc">{</span><span style="color:#cc99cd">this</span><span style="color:#cccccc">.</span>nowState<span style="color:#67cdcc">--</span>_state <span style="color:#67cdcc">=</span> <span style="color:#cc99cd">this</span><span style="color:#cccccc">.</span>stateList<span style="color:#cccccc">[</span><span style="color:#cc99cd">this</span><span style="color:#cccccc">.</span>nowState<span style="color:#cccccc">]</span><span style="color:#f08d49">changeDiv</span><span style="color:#cccccc">(</span>_state<span style="color:#cccccc">.</span>type<span style="color:#cccccc">,</span> _state<span style="color:#cccccc">.</span>num<span style="color:#cccccc">)</span><span style="color:#cccccc">}</span>
<span style="color:#cccccc">}</span>
</code></span></span></span>
#6.5 本章总结
- 策略/状态模式
帮助我们优化 if-else 结构
- 外观模式
一种套餐化接口的思想,提醒我们封装常用方法
- 迭代器模式
帮助我们更好的遍历数据
- 备忘录模式
帮我们缓存以及回到过去的状态
#7 总结
提示
我们的设计模式,要记住其思想,不用记住其结构,结构不是固定;我们通过设计模式主要是提高我们代码的质量