这是我参与 8 月更文挑战的第 11 天,活动详情查看: 8月更文挑战javascript
用于将一个请求封装成一个对象,从而使你可用不一样的请求对客户进行参数化,对请求排队或者记录请求日志,以及执行可撤销的操做。也就是说改模式旨在将函数的调用、请求和操做封装成一个单一的对象。java
function Command(execute, undo, value) {
this.execute = execute;
this.undo = undo;
this.value = value;
}
var AddCommand = function (value) {
return new Command(add, sub, value);
};
var SubCommand = function (value) {
return new Command(sub, add, value);
};
var MulCommand = function (value) {
return new Command(mul, div, value);
};
var DivCommand = function (value) {
return new Command(div, mul, value);
};
复制代码
命令具备如下的优势:设计模式
(1)命令模式使新的命令很容易地被加入到系统里。数组
(2)容许接收请求的一方决定是否要否决请求。缓存
(3)能较容易地设计一个命令队列。markdown
(4)能够容易地实现对请求的撤销和恢复。app
(5)在须要的状况下,能够较容易地将命令记入日志。函数
解释器模式用于构造一个简单的语言解释器,将字符串按照自定义的方式解释执行 ,是一种不经常使用的设计模式。除非从事底层开发本身须要去定义较为复杂的表达式,不然基本上不一样这个设计模式,并且像不少语言其实都有提供动态代码的执行或者VM的功能。post
好比实现一个对字符串判断是不是偶数性能
function Interpreter(str) {
return Number(str) % 2 !== 0;
}
复制代码
优势:
缺点:
基本上是每种语言都会实现的一种模式,提供一种方法顺序访问一个聚合对象中各个元素, 而又无须暴露该对象的内部表示。
function each(arr, fn) {
for (let item of arr) {
fn(item)
}
}
each([1, 2, 3], function(item) {
console.log(item)
})
复制代码
中介者模式主要用于一个系统中存在大量的对象,并且这些大量的对象须要互相通讯,由于两个对象须要通讯,一个对象必需要持有另外一个对象,这样就会致使,系统里,每一个对象都互相引用,会引发混乱,中介者把全部的对象都统一管理起来,其余的对象经过中介者去和别的对象通讯。
咱们能够大体看下Vue的实现
Vue.prototype.$on = function (event: string | Array<string>, fn: Function): Component {
const vm: Component = this
/*若是是数组的时候,则递归$on,为每个成员都绑定上方法*/
if (Array.isArray(event)) {
for (let i = 0, l = event.length; i < l; i++) {
this.$on(event[i], fn)
}
} else {
(vm._events[event] || (vm._events[event] = [])).push(fn)
// optimize hook:event cost by using a boolean flag marked at registration
// instead of a hash lookup
/*这里在注册事件的时候标记bool值也就是个标志位来代表存在钩子,而不须要经过哈希表的方法来查找是否有钩子,这样作能够减小没必要要的开销,优化性能。*/
if (hookRE.test(event)) {
vm._hasHookEvent = true
}
}
return vm
}
Vue.prototype.$emit = function (event: string): Component {
const vm: Component = this
if (process.env.NODE_ENV !== 'production') {
const lowerCaseEvent = event.toLowerCase()
if (lowerCaseEvent !== event && vm._events[lowerCaseEvent]) {
tip(
`Event "${lowerCaseEvent}" is emitted in component ` +
`${formatComponentName(vm)} but the handler is registered for "${event}". ` +
`Note that HTML attributes are case-insensitive and you cannot use ` +
`v-on to listen to camelCase events when using in-DOM templates. ` +
`You should probably use "${hyphenate(event)}" instead of "${event}".`
)
}
}
let cbs = vm._events[event]
if (cbs) {
/*将类数组的对象转换成数组*/
cbs = cbs.length > 1 ? toArray(cbs) : cbs
const args = toArray(arguments, 1)
/*遍历执行*/
for (let i = 0, l = cbs.length; i < l; i++) {
cbs[i].apply(vm, args)
}
}
return vm
}
复制代码
备忘录设计模式很是的适合在缓存还原的场景,就是我把某个状态数据先作缓存,存于内存或者其余的媒介中,在切换回来此状态时直接到缓存中的状态数据给导出,不须要再一步步的进行new操做,提升对象实体生成的效率,提升工做效率和场景体验。
好比,实现一个斐波那契数列的求和
function fn(n) {
if (n < 2) {
return n;
}
return fn(n - 1) + fn(n - 2)
}
复制代码
当咱们把n稍调大的时候,就能够发现速度特别慢,甚至会爆栈。缘由是中间存在了大量的重复计算,咱们来经过备忘录模式作一波优化。
const memento = {};
function fn(n) {
if (n < 2) {
return n;
}
if (memento[n]) {
return memento[n]
}
memento[n] = fn(n - 1) + fn(n - 2)
return memento[n]
}
复制代码
最后打波小广告,美团校招社招内推,不限部门,不限岗位,不限投递数量,海量hc,快来快来~