前端设计模式概论

#1. 代码设计模式

# 我们写代码到底是在写什么?

我们写项目其实就是写模块然后设计它们之间的沟通,设计模式说白了就是帮助我们更好的设计模块, 更好的组织它们之间的沟通。

# 设计模式扮演的角色
  • 帮助我们组织模块

    通过一些设计模式,组织模块间的组成结构

  • 帮助我们设计沟通

    有的设计模式可以帮助我们设计模块间如何沟通

  • 提高代码质量

    通过设计模式,让代码更加优雅

# 设计原则
  1. 开闭原则

    我们的程序要对扩展开放,对修改关闭;我们的程序要给具体使用的时候扩展的接口,但是在具体使用的时候不能让其修改我们的源码, 也就是说我们不用修改源码就能扩展功能,像 vue,react 等都有扩展的接口。

  2. 单一职责原则

    我们的模块只做一件事情,模块的职责越单一越好。

  3. 依赖倒置原则

    我们的上层模块不要依赖与具体的下层模块,应该依赖于抽象

假如下面是一套点餐系统,我们在上层和下层之间加一个抽象层;下层如何变动都不会影响到上层,只需更改抽象层即可。

<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>
  1. 接口隔离原则

我们的接口要细化,功能要单一,一个接口不要调用太多方法,使其能力单一,听起来像单一职责原则;但是 2 者的关注点不同, 单一职责原则主要关注于模块本身,接口隔离原则关注于接口;我们尽量细化接口,每个接口做的事情尽量单一化。

  1. 迪米特法则

我们让 2 个对象之间产生沟通,我们最好让 2 个对象之间知道的越少越好,没必要 2 者之间非常的了解;我们的中介者模式是一个很好体现迪米特法则的设计模式,中介者模式让 2 个对象之间没必要直接的沟通,如果直接沟通需要了解 2 者之间的 api 和彼此的调用方式,这个时候我们可以采用一个中介者来转达我们的需求,而不用彼此知道

  1. 里氏替换原则

它主要关注于继承,它的意义是任何使用父类的地方都可以用子类去替换,直白的说我们子类继承父类的时候,我们的子类必须完全保证继承父类的属性和方法,这样的话父类使用的地方,子类可以进行替换

后面学习到设计模式都是在体现这些设计原则

# 设计模式的分类

  1. 创建型

这些设计模式可以帮助我们优雅地创建对象

  1. 结构型

帮助我们优雅地设计代码结构

  1. 行为型

模块之间行为的模式总结,帮助我们组织模块行为

  1. 技巧型

一些帮助我们优化代码的技巧

# 创建型
  • 工厂模式-大量创建对象

  • 单例模式-全局只能有我一个

  • 建造者模式-精细化组合对象

  • 原型模式-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 的组合与继承

  • 组合(推荐)

    1. javascript 最初没有专门的继承,所以最初 javascript 推崇函数式的编程,然后进行统一组合桥接到一起
    2. 桥接模式可以看出组合的一种体现,组合的好处是耦合低,方便方法复用,方便扩展
  • 继承

    1. es6 出现 class 与 extend,继承的方式多种多样,但是都是各有弊端
    2. 模版方法模式可以看出继承的一种体现,继承的好处是可以自动获得父类的内容与接口,方便统一化

#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>
  1. 用户只管输入他要的命令,不用关心 api

  2. 命令和实现解耦,无论命令发生变动,还是实现发生变动,都不会彼此影响

绘制随数量图片

需求:需要做一个画廊,图片数量和排列顺序随机

<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. 提高代码质量

提高代码质量

  • 高质量的代码,方便后续的一切操作
  • 方便他人阅读

什么是代码质量

  1. 代码整洁
  2. 结构规整,没有漫长的结构
  3. 阅读好理解

#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 总结

提示

我们的设计模式,要记住其思想,不用记住其结构,结构不是固定;我们通过设计模式主要是提高我们代码的质量

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/184377.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

一觉醒来!Keras 3.0史诗级更新,大一统深度学习三大后端框架【Tensorflow/PyTorch/Jax】

不知道大家入门上手机器学习项目是首先入坑的哪个深度学习框架&#xff0c;对于我来说&#xff0c;最先看到的听到的就是Tensorflow了&#xff0c;但是实际上手做项目开发的时候却发现了一个很重要的问题&#xff0c;不容易上手&#xff0c;基于原生的tf框架来直接开发模总是有…

SAP_ABAP_编程基础_内表_创建内表 / 填充内表 / 读取内表 /修改和删除内表行 / 内表排序 / 创建顺序表 / 比较内表 / 初始化内表

SAP ABAP 顾问&#xff08;开发工程师&#xff09;能力模型_Terry谈企业数字化的博客-CSDN博客文章浏览阅读470次。目标&#xff1a;基于对SAP abap 顾问能力模型的梳理&#xff0c;给一年左右经验的abaper 快速成长为三年经验提供超级燃料&#xff01;https://blog.csdn.net/j…

《PFL》论文阅读笔记

一、概要 随着联邦学习的发展&#xff0c;简单的聚合算法已经不在有效。但复杂的聚合算法使得联邦学习训练时间出现新的瓶颈。本文提出了并行联邦学习&#xff08;parallel federated learning&#xff0c;PFL&#xff09;&#xff0c;通过调换中心节点聚合和广播的顺序。本文…

这4个磁盘备份方法可以帮你轻松保护重要数据安全!

怎样备份磁盘中存储的重要数据&#xff1f;在我们的日常工作与学习中&#xff0c;数据丢失的情况时有发生&#xff08;比如自己的照片、视频、文档等被误删或者丢失&#xff09;&#xff0c;多数用户可以通过专业的数据恢复软件来找回数据。但若情况比较严重的话&#xff0c;为…

PyQt6 QPushButton按钮控件

​锋哥原创的PyQt6视频教程&#xff1a; 2024版 PyQt6 Python桌面开发 视频教程(无废话版) 玩命更新中~_哔哩哔哩_bilibili2024版 PyQt6 Python桌面开发 视频教程(无废话版) 玩命更新中~共计32条视频&#xff0c;包括&#xff1a;2024版 PyQt6 Python桌面开发 视频教程(无废话…

【刷题笔记】两数之和II_二分法||二分查找||边界||符合思维方式

两数之和II_二分法||二分查找 1 题目描述 https://leetcode.cn/problems/two-sum-ii-input-array-is-sorted/ 给你一个下标从 1 开始的整数数组 numbers &#xff0c;该数组已按 非递减顺序排列 &#xff0c;请你从数组中找出满足相加之和等于目标数 target 的两个数。如果设…

MYSQL的聚合函数,存储过程的知识点

聚合函数 MySQL提供了多种聚合函数&#xff0c;用于对数据进行汇总计算&#xff1a; - **COUNT()&#xff1a;** 统计行数或非NULL值的数量。 - **SUM()&#xff1a;** 计算某列值的总和。 - **AVG()&#xff1a;** 计算某列值的平均值。 - **MAX()&#xff1a;** 获取某列的…

统信UOS 1060操作系统上更新系统

往期好文&#xff1a;统信UOS/麒麟KYLINOS禁用USB存储 hello&#xff0c;大家好啊&#xff01;在数字化时代&#xff0c;操作系统的安全性和稳定性对我们的日常工作和生活至关重要。今天&#xff0c;我要给大家介绍的是关于在统信UOS 1060操作系统上&#xff0c;如何通过控制中…

Facebook广告投放效果不佳?这些投放技巧我不允许你不知道!

众所周知&#xff0c;Facebook广告对于跨境卖家来说是非常有效的站外引流渠道&#xff0c;通过Facebook广告投放可以提高跨境卖家的产品销量和排名&#xff0c;但是有时明明广告已经投放出去了&#xff0c;却无法被受众看到&#xff0c;完全没有获得成果&#xff0c;或许你会怪…

CRM系统的数据分析和报表功能对企业重要吗?

竞争日益激烈&#xff0c;企业需要更加高效地管理客户关系&#xff0c;以获取更多的商机。为此&#xff0c;许多企业选择使用CRM系统。在CRM中&#xff0c;数据分析功能扮演着重要的角色。下面就来详细说说&#xff0c;CRM系统数据分析与报表功能对企业来说重要吗&#xff1f; …

pandas(八)--实战一下

背景 收到一批数据&#xff0c;数据形式。采集数据的间隔时间是10分钟&#xff0c;全天采集数据&#xff0c;每天的数据量是144条 处理后的数据形式 分析 去除表格中的q的异常值&#xff0c;置为0去除重复行将原始表格中的date分裂成日期和时间缺失的时间点数据补0&#x…

Unity C++交互

一、设置Dll输出。 两种方式&#xff1a; 第一&#xff1a;直接创建动态链接库工程第二&#xff1a;创建的是可执行程序&#xff0c;在visual studio&#xff0c;右键项目->属性(由exe改成dll) 二、生成Dll 根据选项Release或Debug&#xff0c;运行完上面的生成解决方案后…

如何修改Window电脑的远程登陆端口

主要步骤如下&#xff1a; 1、找到运行对话框&#xff0c;一种方法是&#xff1a;开始->附件->运行&#xff1b;另外一种是快捷键winR组合键。 2、Regedit&#xff0c;在对话框中输入regedit命令&#xff0c;然后回车。备份注册表。手动备份注册表 2.1选择“ 开始 ”&am…

如何使用 CSS columns 布局来实现自动分组布局?

最近在项目中碰到这样一个布局&#xff0c;有一个列表&#xff0c;先按照 4 2 的正常顺序排列&#xff0c;当超过 8 个后&#xff0c;会横向重新开始 4 2 的布局&#xff0c;有点像一个个独立的分组&#xff0c;然后水平排列&#xff0c;如下 图中序号是 dom 序列&#xff0c;所…

【算法心得】When data range not large, try Bucket sort

https://leetcode.com/problems/maximum-number-of-coins-you-can-get/description/?envTypedaily-question&envId2023-11-24 I solve this problem by sorting piles first, and choose piles for(let i1;i<(piles.length/3)*2;i2) but: o(≧口≦)o Problem must …

ISCTF2023新生赛Misc部分WP

ISCTF2023新生赛部分WP MISC&#xff1a;签到&#xff1a;你说爱我&#xff1f;尊嘟假嘟&#xff1a;小蓝鲨的秘密&#xff1a;easy_zip:杰伦可是流量明星&#xff1a;蓝鲨的福利&#xff1a;Ez_misc:PNG的基本食用:小猫&#xff1a;MCSOG-猫猫&#xff1a;镜流:stream&#xf…

基于OpenCV的手势识别系统设计与开发

摘要 随着计算机技术与信息处理技术迅速发展&#xff0c;智能化电子设备逐渐进入到日常的生产和生活中&#xff0c;与此同时&#xff0c;人们对电子设备操作过程的便捷化也提出了新的要求&#xff0c;这也促使计算机进行图像处理的技术也得到了发展。近些年兴起的模式识别技术…

1.自动化运维工具Ansible的安装

1.物料准备 四台服务器&#xff0c;其中一个是主控机&#xff0c;三个为host 2.安装 在主控机上安装ansible 2.1 设置EPEL仓库 Ansible仓库默认不在yum仓库中&#xff0c;因此我们需要使用下面的命令启用epel仓库。 yum install epel-release -y2.2 执行安装命令 yum i…

网站上https协议,nginx配置SSL,443端口

nginx配置ssl 要给自己的网站上ssl证书&#xff0c;使用https协议。首先你需要有证书文件&#xff0c;这个文件是你买的服务&#xff0c;买过之后别人会给你。 就是这样的文件&#xff1a; 然后你就把文件上传到服务器的一个位置&#xff0c;你记住这个位置&#xff0c;后面配…

java审计之java反序列化-CC链

介绍 序列化的本质是内存对象到数据流的一种转换&#xff0c;我们知道内存中的东西不具备持久性&#xff0c;但有些场景却需要将对象持久化保存或传输。 在Java工程中&#xff0c;序列化还广泛应用于JMX&#xff0c;RMI&#xff0c;网络传输&#xff08;协议包对象&#xff09…