深入理解JavaScript系列(39):設計模式之適配器模式

來源:互聯網
上載者:User
介紹

適配器模式(Adapter)是將一個類(對象)的介面(方法或屬性)轉化成客戶希望的另外一個介面(方法或屬性),適配器模式使得原本由於介面不相容而不能一起工作的那些類(對象)可以一些工作。速成封裝器(wrapper)。

本文

我們來舉一個例子,鴨子(Dock)有飛(fly)和嘎嘎叫(quack)的行為,而火雞雖然也有飛(fly)的行為,但是其叫聲是咯咯的 (gobble)。如果你非要火雞也要實現嘎嘎叫(quack)這個動作,那我們可以複用鴨子的quack方法,但是具體的叫還應該是咯咯的,此時,我們 就可以建立一個火雞的適配器,以便讓火雞也支援quack方法,其內部還是要調用gobble。

OK,我們開始一步一步實現,首先要先定義鴨子和火雞的抽象行為,也就是各自的方法函數:

//鴨子
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(" 該方法必須被重寫 !");
};

然後再定義具體的鴨子和火雞的建構函式,分別為:

//鴨子
var MallardDuck = function () {
Duck.apply(this);
};
MallardDuck.prototype = new Duck(); //原型是Duck
MallardDuck.prototype.fly = function () {
console.log("可以飛翔很長的距離!");
};
MallardDuck.prototype.quack = function () {
console.log("嘎嘎!嘎嘎!");
};

//火雞
var WildTurkey = function () {
Turkey.apply(this);
};
WildTurkey.prototype = new Turkey(); //原型是Turkey
WildTurkey.prototype.fly = function () {
console.log("飛翔的距離貌似有點短!");
};
WildTurkey.prototype.gobble = function () {
console.log("咯咯!咯咯!");
};

為了讓火雞也支援quack方法,我們建立了一個新的火雞適配器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;
}
};

該建構函式接受一個火雞的執行個體對象,然後使用Duck進行apply,其適配器原型是Duck,然後要重新修改其原型的quack方法,以便內部調 用oTurkey.gobble()方法。其fly方法也做了一些改變,讓火雞連續飛5次(內部也是調用自身的oTurkey.fly()方法)。

調用方法,就很明了了,測試一下便可以知道結果了:

var oMallardDuck = new MallardDuck();
var oWildTurkey = new WildTurkey();
var oTurkeyAdapter = new TurkeyAdapter(oWildTurkey);

//原有的鴨子行為
oMallardDuck.fly();
oMallardDuck.quack();

//原有的火雞行為
oWildTurkey.fly();
oWildTurkey.gobble();

//適配器火雞的行為(火雞調用鴨子的方法名稱)
oTurkeyAdapter.fly();
oTurkeyAdapter.quack();

總結

那合適使用適配器模式好呢?如果有以下情況出現時,建議使用:

  1. 使用一個已經存在的對象,但其方法或屬性介面不符合你的要求;
  2. 你想建立一個可複用的對象,該對象可以與其它不相關的對象或不可見對象(即介面方法或屬性不相容的對象)協同工作;
  3. 想使用已經存在的對象,但是不能對每一個都進行原型繼承以匹配它的介面。對象適配器可以適配它的父物件介面方法或屬性。

另外,適配器模式和其它幾個模式可能容易讓人迷惑,這裡說一下大概的區別:

  1. 適配器和橋接模式雖然類似,但橋接的出發點不同,橋接的目的是將介面部分和實現部分分離,從而對他們可以更為容易也相對獨立的加以改變。而適配器則意味著改變一個已有對象的介面。
  2. 裝飾者模式增強了其它對象的功能而同時又不改變它的介面,因此它對應程式的透明性比適配器要好,其結果是裝飾者支援遞迴組合,而純粹使用適配器則是不可能的。
  3. 代理模式在不改變它的介面的條件下,為另外一個對象定義了一個代理。

參考:https://github.com/tcorral/Design-Patterns-in-Javascript/blob/master/Adapter/index.html

轉自:湯姆大叔

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.