深入理解JavaScript系列(39):設(shè)計(jì)模式之適配器模式詳解
介紹
適配器模式(Adapter)是將一個(gè)類(對(duì)象)的接口(方法或?qū)傩裕┺D(zhuǎn)化成客戶希望的另外一個(gè)接口(方法或?qū)傩裕?,適配器模式使得原本由于接口不兼容而不能一起工作的那些類(對(duì)象)可以一些工作。速成包裝器(wrapper)。
正文
我們來舉一個(gè)例子,鴨子(Dock)有飛(fly)和嘎嘎叫(quack)的行為,而火雞雖然也有飛(fly)的行為,但是其叫聲是咯咯的(gobble)。如果你非要火雞也要實(shí)現(xiàn)嘎嘎叫(quack)這個(gè)動(dòng)作,那我們可以復(fù)用鴨子的quack方法,但是具體的叫還應(yīng)該是咯咯的,此時(shí),我們就可以創(chuàng)建一個(gè)火雞的適配器,以便讓火雞也支持quack方法,其內(nèi)部還是要調(diào)用gobble。
OK,我們開始一步一步實(shí)現(xiàn),首先要先定義鴨子和火雞的抽象行為,也就是各自的方法函數(shù):
//鴨子
var Duck = function(){
};
Duck.prototype.fly = function(){
throw new Error("該方法必須被重寫!");
};
Duck.prototype.quack = function(){
throw new Error("該方法必須被重寫!");
}
//火雞
var Turkey = function(){
};
Turkey.prototype.fly = function(){
throw new Error(" 該方法必須被重寫 !");
};
Turkey.prototype.gobble = function(){
throw new Error(" 該方法必須被重寫 !");
};
然后再定義具體的鴨子和火雞的構(gòu)造函數(shù),分別為:
//鴨子
var MallardDuck = function () {
Duck.apply(this);
};
MallardDuck.prototype = new Duck(); //原型是Duck
MallardDuck.prototype.fly = function () {
console.log("可以飛翔很長(zhǎng)的距離!");
};
MallardDuck.prototype.quack = function () {
console.log("嘎嘎!嘎嘎!");
};
//火雞
var WildTurkey = function () {
Turkey.apply(this);
};
WildTurkey.prototype = new Turkey(); //原型是Turkey
WildTurkey.prototype.fly = function () {
console.log("飛翔的距離貌似有點(diǎn)短!");
};
WildTurkey.prototype.gobble = function () {
console.log("咯咯!咯咯!");
};
為了讓火雞也支持quack方法,我們創(chuàng)建了一個(gè)新的火雞適配器TurkeyAdapter:
var TurkeyAdapter = function(oTurkey){
Duck.apply(this);
this.oTurkey = oTurkey;
};
TurkeyAdapter.prototype = new Duck();
TurkeyAdapter.prototype.quack = function(){
this.oTurkey.gobble();
};
TurkeyAdapter.prototype.fly = function(){
var nFly = 0;
var nLenFly = 5;
for(; nFly < nLenFly;){
this.oTurkey.fly();
nFly = nFly + 1;
}
};
該構(gòu)造函數(shù)接受一個(gè)火雞的實(shí)例對(duì)象,然后使用Duck進(jìn)行apply,其適配器原型是Duck,然后要重新修改其原型的quack方法,以便內(nèi)部調(diào)用oTurkey.gobble()方法。其fly方法也做了一些改變,讓火雞連續(xù)飛5次(內(nèi)部也是調(diào)用自身的oTurkey.fly()方法)。
調(diào)用方法,就很明了了,測(cè)試一下便可以知道結(jié)果了:
var oMallardDuck = new MallardDuck();
var oWildTurkey = new WildTurkey();
var oTurkeyAdapter = new TurkeyAdapter(oWildTurkey);
//原有的鴨子行為
oMallardDuck.fly();
oMallardDuck.quack();
//原有的火雞行為
oWildTurkey.fly();
oWildTurkey.gobble();
//適配器火雞的行為(火雞調(diào)用鴨子的方法名稱)
oTurkeyAdapter.fly();
oTurkeyAdapter.quack();
總結(jié)
那合適使用適配器模式好呢?如果有以下情況出現(xiàn)時(shí),建議使用:
1.使用一個(gè)已經(jīng)存在的對(duì)象,但其方法或?qū)傩越涌诓环夏愕囊螅?br />
2.你想創(chuàng)建一個(gè)可復(fù)用的對(duì)象,該對(duì)象可以與其它不相關(guān)的對(duì)象或不可見對(duì)象(即接口方法或?qū)傩圆患嫒莸膶?duì)象)協(xié)同工作;
3.想使用已經(jīng)存在的對(duì)象,但是不能對(duì)每一個(gè)都進(jìn)行原型繼承以匹配它的接口。對(duì)象適配器可以適配它的父對(duì)象接口方法或?qū)傩浴?/p>
另外,適配器模式和其它幾個(gè)模式可能容易讓人迷惑,這里說一下大概的區(qū)別:
1.適配器和橋接模式雖然類似,但橋接的出發(fā)點(diǎn)不同,橋接的目的是將接口部分和實(shí)現(xiàn)部分分離,從而對(duì)他們可以更為容易也相對(duì)獨(dú)立的加以改變。而適配器則意味著改變一個(gè)已有對(duì)象的接口。
2.裝飾者模式增強(qiáng)了其它對(duì)象的功能而同時(shí)又不改變它的接口,因此它對(duì)應(yīng)程序的透明性比適配器要好,其結(jié)果是裝飾者支持遞歸組合,而純粹使用適配器則是不可能的。
3.代理模式在不改變它的接口的條件下,為另外一個(gè)對(duì)象定義了一個(gè)代理。
- JavaScript適配器模式詳解
- javascript設(shè)計(jì)模式之Adapter模式【適配器模式】實(shí)現(xiàn)方法示例
- JavaScript設(shè)計(jì)模式之適配器模式介紹
- 詳解JavaScript實(shí)現(xiàn)設(shè)計(jì)模式中的適配器模式的方法
- javascript設(shè)計(jì)模式 – 適配器模式原理與應(yīng)用實(shí)例分析
- JavaScript設(shè)計(jì)模式學(xué)習(xí)之適配器模式
- JavaScript 設(shè)計(jì)模式之組合模式解析
- JavaScript組合模式學(xué)習(xí)要點(diǎn)
- 設(shè)計(jì)模式中的組合模式在JavaScript程序構(gòu)建中的使用
- javascript設(shè)計(jì)模式 – 組合模式原理與應(yīng)用實(shí)例分析
- JavaScript設(shè)計(jì)模式開發(fā)中組合模式的使用教程
- javascript適配器模式和組合模式原理與實(shí)現(xiàn)方法詳解
相關(guān)文章
JavaScript中CreateTextFile函數(shù)
JavaScript中CreateTextFile函數(shù)是創(chuàng)建指定的文件名并返回一個(gè) TextStream 對(duì)象,可以使用這個(gè)對(duì)象對(duì)文件進(jìn)行讀寫2020-08-08javaScript parseInt字符轉(zhuǎn)化為數(shù)字函數(shù)使用小結(jié)
前幾天做網(wǎng)站的時(shí)候需要講數(shù)據(jù)庫中的時(shí)間讀取到變量中進(jìn)行使用,用到parseInt函數(shù),講字符轉(zhuǎn)化為數(shù)字。2009-11-11JavaScript 中的執(zhí)行上下文和執(zhí)行棧實(shí)例講解
這篇文章主要介紹了JavaScript 中的執(zhí)行上下文和執(zhí)行棧實(shí)例講解,文中實(shí)例講解的很清晰,有感興趣的同學(xué)可以研究下2021-02-02簡(jiǎn)介JavaScript中的unshift()方法的使用
這篇文章主要介紹了簡(jiǎn)介JavaScript中的unshift()方法的使用,是JS入門學(xué)習(xí)中的基礎(chǔ)知識(shí),需要的朋友可以參考下2015-06-06鍵盤 keycode的值 javascript時(shí)觸發(fā)事件時(shí)很有用的要素
鍵盤keycode的值 編寫javascript時(shí)觸發(fā)事件時(shí)很有用的要素,大家可以收藏一下。2009-11-11深入理解JavaScript系列(41):設(shè)計(jì)模式之模板方法詳解
這篇文章主要介紹了深入理解JavaScript系列(41):設(shè)計(jì)模式之模板方法詳解,模板方法(TemplateMethod)定義了一個(gè)操作中的算法的骨架,而將一些步驟延遲到子類中,模板方法使得子類可以不改變一個(gè)算法的結(jié)構(gòu)即可重定義該算法的某些特定步驟,需要的朋友可以參考下2015-03-03