本文参考于
《javascript模式》
,因此会大量内容会和书中相同,手上有这本书的朋友可以直接看书。因为我的记忆习惯是抄书,所以我会先抄写下来再发到博客上。
单体模式
单体模式思想在于保证一个特定类仅有一个实例,意味着当你第二次使用同一个类创建信对象时,应得到和第一次创建对象完全相同。
方法一
1 | function Universe() { |
缺点
instance 属性暴露。
方法二
使用闭包
1 | function Universe() { |
缺点
因为重写了构造函数,constructor 还是指向了老的构造函数,且实例化后在添加原型属性也是不一样的。如下
1 | var uni = new Universe() |
方法三
解决方法二
问题。
1 | function Universe() { |
方法四
自运行函数。
1 | var Universe |
工厂模式
工厂模式是为了创建对象。
例子
- 公共构造函数 CarMaker
- 名为 factory 的 CarMaker 静态方法来创建 car 对象
1 | var corolla = CarMaker.factory('compact') |
实现
1 | function CarMaker() {} |
内置工厂对象
Object() 构造函数即为内置工厂对象。
迭代器模式
有一个包含某种数据集合的对象,该数据可能存储在一个复杂数据结构内部,而要提供一个简单方法讷讷感访问到数据结构中没一个元素。
- next() 下一个
- hasNext() 是否有下一个
- reWind() 重置指针
- current() 返回当前
1 | var agg = (function() { |
装饰者模式
可以在运行时候添加附加功能到对象中,他的一个方便特征在于其预期行为的可定制和可配置特性。
例子 假设在开发一个销售商品的 Web 应用,每一笔信销售都是一个人新的 sale 对象。该对象“知道”有关项目的价格,并可以通过 getPrice() 方法返回加个。
根据不同情况,可以用额外的功能装饰此对象。
假设客户在魁北克省,买房需要支付联邦税和魁北克省税,则此时需要调用联邦税装饰者和魁北克省税装饰者。
1 | var sale = new Sale(100) |
并且装饰是可选的,例如不再魁北克省有可能没有省税。
方法一
1 | function Sale(price) { |
方法二
此方法使用列表实现,而且相对来说比较好理解一点。本质就是把装饰者名称保存到一个列表中并且一次调用此列表中的方法。
1 | function Sale(price) { |
策略模式
策略模式支持在运行时候选择算法。例如用在表单验证问题上,可以创建一个具有 validate() 方法的验证器对象,无论表单具体类型是什么,该方法都会被调用,并且返回结果或者错误信息。
1 | var validator = { |
策略模式定义及例子实现参考与《javascript 模式》及 汤姆大叔的博客
外观模式
外观模式即让多个方法一起被调用
例如。 stopPropagation() 和 preventDefault() 兼容性一起调用。
1 | var myEvent = { |
代理模式
在代理模式中,一个对象充当另外一个对象的接口,和外观模式区别是:外观模式是合并调用多个方法。
代理模式是介于对象的客户端和对象本身之间,并且对该对象的访问进行保护。
包裹例子
现在有个包裹,卖家要把这个包裹寄给 gary,则需要通过快递公司寄过来,此时快递公司就是一个 proxy
1 | var package = function(receiver) { |
论坛权限管理例子
本例子参考与 大熊君
- 权限列表
- 发帖 1
- 帖子审核 2
- 删帖 3
- 留言、回复 4
用户 | 代码 | 权限 |
---|---|---|
注册用户 | 001 | 1 4 |
论坛管理员 | 002 | 2 3 4 |
系统管理员 | 003 | 1 2 3 4 |
游客 | 000 | null |
用户类
1 | function User(name, code) { |
论坛类
1 | function Forum(user) { |
运行
1 | new Forum(new User('administartor', '003')) |
中介者模式
中介者模式可以让多个对象之间松耦合,并降低维护成本
例如:游戏程序,两名玩家分别给与半分钟时间来竞争决出胜负(谁按键的次数多胜出,这里玩家 1 按 1,玩家 2 按 0)
- 计分板(scoreboard)
- 中介者 (mediator)
中介者知道所有其他对象的信息。他与输入设备(此时是键盘)进行通信并处理键盘上的按键时间,之后还将消息通知玩家。玩家玩游戏同时(每一分都更新自己分数)还要通知中介者他所做的事情。中介者将更新后的分数传达给计分板。
除了中介者莫有对象知道其他对象。
图示
1 | function Player(name) { |
观察者模式
观察者模式在 javascript 中使用非常广泛。所有的浏览器时间就是该模式的实现,node.js 中的 events 也是此模式实现。
此模式另一个名称是 订阅/发布模式
。
设计这种模式原因是促进形成松散耦合,在这种模式中,并不是一个对象调用另一个对象的方法,而是一个对象订阅另一个对象的特定活动并在状态改编后获得通知。订阅者因此也成为观察者,而被观察的对象成为发布者或者主题。当发生了一个重要事件时候发布者会通知(调用)所有订阅者并且可能经常已事件对象的形式传递消息。
参考:nodejs 的 EventEmitter
小结
单体模式
针对一个类仅创建一个对象。
工厂模式
根据字符串制定类型在运行时创建对象的方法。
迭代器模式
提供一个 API 来遍历或者操作复杂的自定义数据结构。
装饰者模式
通过从预定义装饰者对象中添加功能,从而在运行时侯调整对象
策略模式
在悬在最佳策略以处理特定任务的时候仍然保持相同的接口。
外观模式
通过把常用方法包装到一个新方法中,从来提供一个更为便利的 API。
代理模式
通过包装一个对象从而控制对它的访问,其中主要方法是将方位聚集为租或者仅当真正必要时侯才执行访问,从未避免高昂的操作开销。
终结者模式
通过是你的对象之间相互不直接“通话”,而是通过一个中介者对子昂进行通信,从而形成松散耦合。
观察者模式
通过创建“可观察”的对象,当发生一个感兴趣的事件时可将改时间通告给所有观察者从而形成松散耦合。