前言
從今天開始我們開始講【結(jié)構(gòu)型】設(shè)計模式,【結(jié)構(gòu)型】設(shè)計模式有如下幾種:適配器模式、橋接模式、組合模式、裝飾模式、外觀模式、享元模式、代理模式?!緞?chuàng)建型】的設(shè)計模式解決的是對象創(chuàng)建的問題,那【結(jié)構(gòu)型】設(shè)計模式解決的是類和對象的組合關(guān)系的問題。
今天我們就開始講【結(jié)構(gòu)型】設(shè)計模式里面的第一個設(shè)計模式,中文名稱:適配器模式,英文名稱:Adapter Pattern
。說起這個模式其實很簡單,在現(xiàn)實生活中也有很多實例,比如:我們手機的充電器,充電器的接頭,有的是把兩相電轉(zhuǎn)換為三相電的,當(dāng)然也有把三相電轉(zhuǎn)換成兩相電的。我們經(jīng)常使用筆記本電腦,筆記本電腦的工作電壓和我們家里照明電壓是不一致的,當(dāng)然也就需要充電器把照明電壓轉(zhuǎn)換成筆記本的工作電壓,只有這樣筆記本電腦才可以正常工作。我們只要記住一點,適配就是轉(zhuǎn)換,把不能在一起工作的兩樣?xùn)|西通過轉(zhuǎn)換,讓他們可以在一起工作。Adapter模式主要應(yīng)用于“希望復(fù)用一些現(xiàn)存的類,但是接口又與復(fù)用環(huán)境要求不一致的情況”,在遺留代碼復(fù)用、類庫遷移等方面非常有用。
適配器模式的定義
在軟件系統(tǒng)中,由于應(yīng)用環(huán)境的變化,常常需要將“一些現(xiàn)存的對象”放在新的環(huán)境中應(yīng)用,但是新環(huán)境要求的接口是這些現(xiàn)存對象所不滿足的。如何應(yīng)對這種“遷移的變化”?如何既能利用現(xiàn)有對象的良好實現(xiàn),同時又能滿足新的應(yīng)用環(huán)境所要求的接口?將一個類的接口轉(zhuǎn)換成客戶希望的另一個接口,Adapter模式使得原本由于接口不兼容而不能一起工作的那些類可以一起工作。
適配器模式的組成
- 目標(biāo)角色(Target):定義Client使用的與特定領(lǐng)域相關(guān)的接口。
- 客戶角色(Client):與符合Target接口的對象協(xié)同。
- 被適配角色(Adaptee):定義一個已經(jīng)存在并已經(jīng)使用的接口,這個接口需要適配。
- 適配器角色(Adapter) :適配器模式的核心。它將對被適配Adaptee角色已有的接口轉(zhuǎn)換為目標(biāo)角色Target匹配的接口。對Adaptee的接口與Target接口進行適配.。
適配器模式的實現(xiàn)
由于適配器模式有兩種實現(xiàn)結(jié)構(gòu),對象適配器和類適配器,分別進行實現(xiàn):
對象適配器實現(xiàn)
兩插腳
/// <summary>
/// 我家只有2個孔的插座,也就是適配器模式中的目標(biāo)(Target)角色,這里可以寫成抽象類或者接口
/// </summary>
public class TwoHoleTarget
{
// 客戶端需要的方法
public virtual void Request()
{
Console.WriteLine("我是2個孔的插頭....");
}
}
三插腳
/// <summary>
/// 筆記本電源適配器是有3個柱子的插頭,源角色——需要適配的類(Adaptee)
/// </summary>
public class ThreeHoleAdaptee
{
public void SpecificRequest()
{
Console.WriteLine("我是3個孔的插頭....");
}
}
適配器
/// <summary>
/// 適配器類,TwoHole這個對象寫成接口或者抽象類更好,面向接口編程嘛
/// </summary>
public class ThreeToTwoAdapter : TwoHoleTarget
{
// 引用兩個孔插頭的實例,從而將客戶端與TwoHole聯(lián)系起來
private ThreeHoleAdaptee threeHoleAdaptee = new ThreeHoleAdaptee();
//TODO:這里可以繼續(xù)增加適配的對象
/// <summary>
/// 實現(xiàn)2個孔插頭接口方法
/// </summary>
public override void Request()
{
//可以做具體的轉(zhuǎn)換工作
threeHoleAdaptee.SpecificRequest();
}
}
調(diào)用
/// <summary>
/// 家里只有兩個孔的插座,也懶得買插線板了,還要花錢,
/// 但是筆記本的電源適配器是一個有3個小柱子的插頭,明顯直接搞不定,那就適配吧
///</summary>
/// </summary>
public void RunTest()
{
//現(xiàn)在就可以使用三插給筆記本充電了
TwoHoleTarget homeTwoHole = new ThreeToTwoAdapter();
homeTwoHole.Request();
}
類適配器實現(xiàn)
兩插腳
/// <summary>
/// 我家只有2個孔的插座,也就是適配器模式中的目標(biāo)角色(Target),這里只能是接口,也是類適配器的限制
/// </summary>
public interface ITwoHoleTarget
{
void Request();
}
三插腳
/// <summary>
/// 3個孔的插頭,源角色——需要適配的類(Adaptee)
/// </summary>
public abstract class ThreeHoleAdaptee2
{
public void SpecificRequest2()
{
Console.WriteLine("我是3個孔的插頭。。。。");
}
}
適配器
/// <summary>
/// 適配器類,接口要放在類的后面,在此無法適配更多的對象,這是類適配器的不足
/// </summary>
public class ThreeToTwoAdapter2 : ThreeHoleAdaptee2, ITwoHoleTarget
{
/// <summary>
/// 實現(xiàn)2個孔插頭接口方法
/// </summary>
public void Request()
{
// 調(diào)用3個孔插頭方法
this.SpecificRequest2();
}
}
調(diào)用
public void RunTest()
{
ITwoHoleTarget change = new ThreeToTwoAdapter2();
change.Request();
}
適配器模式優(yōu)缺點
適配器模式用來解決現(xiàn)有對象與客戶端期待接口不一致的問題,下面詳細(xì)總結(jié)下兩種適配器形式的優(yōu)缺點
類的適配器模式:
優(yōu)點:
-
可以在不修改原有代碼的基礎(chǔ)上來復(fù)用現(xiàn)有類,很好地符合 “開閉原則”。
-
可以重新定義Adaptee(被適配的類)的部分行為,因為在類適配器模式中,Adapter是Adaptee的子類。
-
僅僅引入一個對象,并不需要額外的字段來引用Adaptee實例(這個即是優(yōu)點也是缺點)。
缺點:
-
用一個具體的Adapter類對Adaptee和Target進行匹配,當(dāng)如果想要匹配一個類以及所有它的子類時,類的適配器模式就不能勝任了。因為類的適配器模式中沒有引入Adaptee的實例,光調(diào)用this.SpecificRequest方法并不能去調(diào)用它對應(yīng)子類的SpecificRequest方法。
-
采用了 “多繼承”的實現(xiàn)方式,帶來了不良的高耦合。
對象的適配器模式:
優(yōu)點:
-
可以在不修改原有代碼的基礎(chǔ)上來復(fù)用現(xiàn)有類,很好地符合 “開閉原則”(這點是兩種實現(xiàn)方式都具有的)文章來源:http://www.zghlxwxcb.cn/news/detail-687428.html
-
采用 “對象組合”的方式,更符合松耦合。文章來源地址http://www.zghlxwxcb.cn/news/detail-687428.html
缺點:
- 使得重定義Adaptee的行為較困難,這就需要生成Adaptee的子類并且使得Adapter引用這個子類而不是引用Adaptee本身。
到了這里,關(guān)于【23種設(shè)計模式】適配器模式(六)的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!