首先很抱歉近期公務繁忙沒來得及更新...... 為了適應節奏,先先丟擲兩個我認為相對簡單、常用的用來節省開發效率的模式,使用的場景也是很多的,相對沒有什麼難點,這裡結合場景我總結了一下。(本章適合快速閱讀)
介面卡模式
- 組建與元件間的適配
- 類與類之間的適配
- 方法與方法間的適配
- 資料結構和資料結構之間的適配
舉個例子:
usb目前已經不滿足我們主流手機的快充功能了,需要用到type-c介面,我們肯定不會把線剪短換上一個type-c的頭的,我們完全可以通過買一個usb轉type-c的轉接頭來解決我們這個問題。 再多的例子就不講了:)
underscore介面卡
假設,注意是假設,公司有一個框架NB.js,他的語法以及實現形式基本和underscore.js相似,例如each操作:
//NB.js
NB.each([1,2,3],function(key,value){
console.log(this.location.href + '?'+value)
},window)
複製程式碼
//underscore.js
_.each([1,2,3],function(value,key){
console.log(this.location.href + '?'+value)
},window)
複製程式碼
兩個框架的key,value順序是不一樣的。 公司新招了一批同事,他們用過underscore.js但是完全沒聽說過NB.js,公司時間緊任務重,領導決定,先讓公司同事使用underscore的方式使用內部的框架,逐步完善NB.js文件。
這個任務交給你,但總不能對NB.js進行大量的修改,就像上面轉接頭的問題,我們換一個轉接頭就好了:
window.NB = NB = _ ; //underscore轉NB介面卡。
複製程式碼
引數介面卡
function doSomeThing(name,id,color,height,width){
}
doSomeThing('input1','99899','red','200','200')
複製程式碼
這樣的一個函式有多個固定順序的引數,我們知道顯然是不友好的,我們寫函式的時候一定要避免這樣的問題,這樣會顯得很low
,首先就要想到適配
function doSomeThing(obj){
var adapter = {
name:'name',
id:'001',
color:'yellow',
height:'100',
width:'100'
};
for(var i in adapter){
adapter[i] = obj[i] || adapter[i];
}
console.log(adapter);
}
var obj = {color:'red'}
doSomeThing(obj)
//object {name: "name", id: "001", color: "red", height: "100", width: "100"}
複製程式碼
上面的問題其實很多同學早就知道了,還有一種情況就是,前後分離的開發過程中,後臺人員習慣返回的格式跟全端人員預期的不一樣,我們也可以進行適配。
// 後端返回Object,前端需要Array
$.ajax({
url:xxx.action,
success:function(data){
doSomeThing(dataAdapter(data));
}
})
function dataAdapter(obj){
return [obj['name],obj['id'],obj['color'],obj['height'],obj['width']];
}
複製程式碼
像這樣,後端有任何變化我們只需要修改dataAdapter函式就好,其他的通途大家自行腦補:), 其實各種設計模式的宗旨都是低耦合
,易維護
。
裝飾模式
在原型不變的基礎是,通過對他進行包裝,附加屬性,附加方法,使原有的物件、函式能滿足更復雜的需求。因為已經說了裝飾
,所以只是新增新功能時候可以用。
舉個最簡單的例子:
系統中有 一些 按鈕,目前每個按鈕點選後彈出你好
,現在需要在彈出你好過5秒之後在彈出再見
更具體的大家自己腦補,很常見的需求。
有的人開始馬上動手寫了:
<button id="A"></button>
//原來的
var A = document.getElementById('A');
A.onclick = function(){
alert(1)
};
//修改後的
var A = document.getElementById('A');
A.onclick = function(){
alert(1);
setTimeout(function(){
alert(2)
},5000)
};
複製程式碼
當你沾沾自喜時,你發現還有99個按鈕要改......當你真的完成了這個不可思議的任務後,你發現需求變了......好那我們還是儘快使用裝飾者模式
吧:
var A = document.getElementById('A');
A.onclick = function(){
alert(1)
}
//裝飾者
var decorator = function (id,fn){
var dom = document.getElementById(id);
if(typeof dom.onclick === 'function'){
var oldClickFn = dom.onclick;
dom.onclick = function(){
oldClickFn();
fn();
}
}else{
dom.onclick = fn;
}
}
//利用裝飾者對元素增加事件。
decorator('A',function(){
setTimeout(function(){
alert(2)
},5000)
})
複製程式碼
這樣需求改了也不怕了,我們只要修改decorator
函式就好了。
當然隨手寫的也有缺點,我們的引數還是按照順序來排列的,同學們可以參考上面講的介面卡模式,方便以後維護增加程式碼!decorator是全域性的,有興趣可以參考javascript
名稱空間問題,總之,程式碼是越寫越優雅的。
介面卡和裝飾器的不同之處
- 介面卡的方法是對原有物件進行適配,新增的方法與原有方法功能大致相似,只是換了一種更加便利與我們開發的形式,但是裝飾者提供的方法是有區別的,一般都是比之前的更加豐滿,彌補之前的不足之處。
- 裝飾者模式中可以不瞭解原有功能,並且原有的方法照樣可以原封不動的使用,如果原有的方法不能用了,說明你的模式有問題,是不可取的。
PS:
最近私事比較多,設計模式的文章以後的更新頻率是一週一章,比較複雜的單獨一章,比較簡單或關聯較大的兩章並一章,本章5分鐘閱讀流水賬,希望大家共同努力。