這是我參與 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,快來快來~