一 概述
定義:擴充卡模式将某個類的接口轉換成用戶端期望的另一個接口表示,主的目的是相容性,讓原本因接口不比對不能一起工作的兩個類可以協同工作。其别名為包裝器(Wrapper)。
屬于結構型模式
主要分為三類:類擴充卡模式、對象的擴充卡模式、接口的擴充卡模式。
本文定義:
需要被适配的類、接口、對象(我們有的),簡稱 src(source)
最終需要的輸出(我們想要的),簡稱 dst (destination,即Target)
擴充卡稱之為 Adapter 。
一句話描述擴充卡模式的感覺: src->Adapter->dst,即src以某種形式(三種形式分别對應三種擴充卡模式)給到Adapter裡,最終轉化成了dst。
使用場景:
1 系統需要使用現有的類,而這些類的接口不符合系統的需要。
2 想要建立一個可以重複使用的類,用于與一些彼此之間沒有太大關聯的一些類,包括一些可能在将來引進的類一起工作。
3 需要一個統一的輸出接口,而輸入端的類型不可預知。
二 類擴充卡模式
一句話描述:Adapter類,通過繼承 src類,實作 dst 類接口,完成src->dst的适配。
我們通過一個最常用的例子來說明
生活中最常見的就是充電器,220V的交流電被轉換成5V的直流電,充電器在其中就擔當了擴充卡的功能
既然我們是進行适配,那就說明是基于某一個功能點的實作,是以我們先定義一個輸出220v交流電的功能,這個功能如下
/// <summary>
/// 220V電壓
/// </summary>
public class Voltage220
{
public int output220v()
{
int src = 220;
Console.WriteLine("我是" + src + "伏電壓");
return src;
}
}
定義一個接口,接口的方法簽名是轉換(220V-5V)
/// <summary>
/// 客戶需要的5V電壓接口
/// </summary>
public interface Voltage5
{
/// <summary>
/// 輸出5V
/// </summary>
/// <returns></returns>
int output5v();
}
接下去我們開始定義擴充卡類
!!!注意點
1、繼承後來的類
2、實作擴充卡接口
/// <summary>
/// 類擴充卡
/// </summary>
public class VoltageAdapter : Voltage220, Voltage5
{
public int output5v()
{
int src = new Voltage220().output220v();
Console.WriteLine("擴充卡工作開始适配電壓");
int dst = src / 44;
Console.WriteLine("适配完成後輸出電壓:" + dst);
return dst;
}
}
此時我們需要一個裝置,使用擴充卡檢視功能是否正确
定義一個手機類,實作轉換功能
Mobile.charging(擴充卡 box1)
執行個體化手機,調用充電方法,形參是擴充卡的執行個體
/// <summary>
/// 手機類
/// </summary>
public class Mobile
{
/// <summary>
/// 充電方法
/// </summary>
/// <param name="voltage5"></param>
public void charging(Voltage5 voltage5)
{
if (voltage5.output5v() == 5)
{
Console.WriteLine("電壓剛剛好5V,開始充電");
}
else if (voltage5.output5v() > 5)
{
Console.WriteLine("電壓超過5V,都閃開 我要變成note7了");
}
}
}
功能實作
/// <summary>
/// 類擴充卡
/// </summary>
public static void ClassStart()
{
Console.WriteLine("===============類擴充卡==============");
Mobile mobile = new Mobile();
mobile.charging(new VoltageAdapter());
}
三 對象擴充卡
基本思路和類的擴充卡模式相同,隻是将Adapter類作修改,這次不繼承src類,而是持有src類的執行個體,以解決相容性的問題。
即:持有 src類,實作 dst 類接口,完成src->dst的适配。
(根據“合成複用原則”,在系統中盡量使用關聯關系來替代繼承關系,是以大部分結構型模式都是對象結構型模式。)
/// <summary>
/// 對象擴充卡
/// </summary>
public class VoltageAdapter2 : Voltage5
{
private Voltage220 voltage220;
public VoltageAdapter2(Voltage220 voltage220)
{
this.voltage220 = voltage220;
}
public int output5v()
{
int dst = 0;
if (null != voltage220)
{
int src = voltage220.output220v();
Console.WriteLine("對象擴充卡工作,開始适配電壓");
dst = src / 44;
Console.WriteLine("适配完成後輸出電壓:" + dst);
}
return dst;
}
}
/// <summary>
/// 對象擴充卡
/// </summary>
public static void ObjectStart()
{
Console.WriteLine("===============對象擴充卡==============");
VoltageAdapter2 voltageAdapter2=new VoltageAdapter2(new Voltage220());
Mobile mobile = new Mobile();
mobile.charging(voltageAdapter2);
}
小結:
對象擴充卡和類擴充卡其實算是同一種思想,隻不過實作方式不同。
根據合成複用原則,組合大于繼承,
是以它解決了類擴充卡必須繼承src的局限性問題,也不再強求dst必須是接口。
同樣的它使用成本更低,更靈活