c#設(shè)計模式 適配器模式詳細(xì)介紹
更新時間:2012年10月29日 21:24:22 作者:
結(jié)構(gòu)模式(Structural Pattern)描述如何將類或者對象結(jié)合在一起形成更大的結(jié)構(gòu)。結(jié)構(gòu)模式描述兩種不同的東西:類與類的實例。根據(jù)這一點,結(jié)構(gòu)模式可以分為類的結(jié)構(gòu)模式和對象的結(jié)構(gòu)模式
后續(xù)內(nèi)容將包括以下結(jié)構(gòu)模式:
適配器模式(Adapter):Match interfaces of different classes合成模式(Composite):A tree structure of simple and composite objects裝飾模式(Decorator):Add responsibilities to objects dynamically代理模式(Proxy):An object representing another object享元模式(Flyweight):A fine-grained instance used for efficient sharing門面模式(Facade):A single class that represents an entire subsystem橋梁模式(Bridge):Separates an object interface from its implementation
一、 適配器(Adapter)模式
適配器模式把一個類的接口變換成客戶端所期待的另一種接口,從而使原本接口不匹配而無法在一起工作的兩個類能夠在一起工作。
名稱由來
這很像變壓器(Adapter),變壓器把一種電壓變換成另一種電壓。美國的生活用電電壓是110V,而中國的電壓是220V。如果要在中國使用美國電器,就必須有一個能把220V電壓轉(zhuǎn)換成110V電壓的變壓器。這個變壓器就是一個Adapter。
Adapter模式也很像貨物的包裝過程:被包裝的貨物的真實樣子被包裝所掩蓋和改變,因此有人把這種模式叫做包裝(Wrapper)模式。事實上,大家經(jīng)常寫很多這樣的Wrapper類,把已有的一些類包裝起來,使之有能滿足需要的接口。
適配器模式的兩種形式
適配器模式有類的適配器模式和對象的適配器模式兩種。我們將分別討論這兩種Adapter模式。
二、 類的Adapter模式的結(jié)構(gòu):

由圖中可以看出,Adaptee類沒有Request方法,而客戶期待這個方法。為了使客戶能夠使用Adaptee類,提供一個中間環(huán)節(jié),即類Adapter類,Adapter類實現(xiàn)了Target接口,并繼承自Adaptee,Adapter類的Request方法重新封裝了Adaptee的SpecificRequest方法,實現(xiàn)了適配的目的。
因為Adapter與Adaptee是繼承的關(guān)系,所以這決定了這個適配器模式是類的。
該適配器模式所涉及的角色包括:
目標(biāo)(Target)角色:這是客戶所期待的接口。因為C#不支持多繼承,所以Target必須是接口,不可以是類。
源(Adaptee)角色:需要適配的類。
適配器(Adapter)角色:把源接口轉(zhuǎn)換成目標(biāo)接口。這一角色必須是類。
三、 類的Adapter模式示意性實現(xiàn):
下面的程序給出了一個類的Adapter模式的示意性的實現(xiàn):
// Class Adapter pattern -- Structural example
using System;
// "ITarget"
interface ITarget
{
// Methods
void Request();
}
// "Adaptee"
class Adaptee
{
// Methods
public void SpecificRequest()
{
Console.WriteLine("Called SpecificRequest()" );
}
}
// "Adapter"
class Adapter : Adaptee, ITarget
{
// Implements ITarget interface
public void Request()
{
// Possibly do some data manipulation
// and then call SpecificRequest
this.SpecificRequest();
}
}
/**//// <summary>
/// Client test
/// </summary>
public class Client
{
public static void Main(string[] args)
{
// Create adapter and place a request
ITarget t = new Adapter();
t.Request();
}
}
四、 對象的Adapter模式的結(jié)構(gòu):
該適配器模式所涉及的角色包括:
目標(biāo)(Target)角色:這是客戶所期待的接口。目標(biāo)可以是具體的或抽象的類,也可以是接口。
源(Adaptee)角色:需要適配的類。
適配器(Adapter)角色:通過在內(nèi)部包裝(Wrap)一個Adaptee對象,把源接口轉(zhuǎn)換成目標(biāo)接口。
五、 對象的Adapter模式示意性實現(xiàn):
下面的程序給出了一個類的Adapter模式的示意性的實現(xiàn):
// Adapter pattern -- Structural example
using System;
// "Target"
class Target
{
// Methods
virtual public void Request()
{
// Normal implementation goes here
}
}
// "Adapter"
class Adapter : Target
{
// Fields
private Adaptee adaptee = new Adaptee();
// Methods
override public void Request()
{
// Possibly do some data manipulation
// and then call SpecificRequest
adaptee.SpecificRequest();
}
}
// "Adaptee"
class Adaptee
{
// Methods
public void SpecificRequest()
{
Console.WriteLine("Called SpecificRequest()" );
}
}
/**//// <summary>
/// Client test
/// </summary>
public class Client
{
public static void Main(string[] args)
{
// Create adapter and place a request
Target t = new Adapter();
t.Request();
}
}
六、 在什么情況下使用適配器模式
在以下各種情況下使用適配器模式:
1、 系統(tǒng)需要使用現(xiàn)有的類,而此類的接口不符合系統(tǒng)的需要。
2、 想要建立一個可以重復(fù)使用的類,用于與一些彼此之間沒有太大關(guān)聯(lián)的一些類,包括一些可能在將來引進(jìn)的類一起工作。這些源類不一定有很復(fù)雜的接口。
3、 (對對象適配器而言)在設(shè)計里,需要改變多個已有子類的接口,如果使用類的適配器模式,就要針對每一個子類做一個適配器,而這不太實際。
七、 一個實際應(yīng)用Adapter模式的例子
下面的程序演示了Class Adapter與Object Adapter的應(yīng)用。
// Example of implementing the Adapter pattern
using System;
// Target
public interface ICar
{
void Drive();
}
// Direct use without Adapter
public class CToyota : ICar
{
public void Drive()
{
Console.WriteLine("Vroom Vroom, we're off in our Toyota");
}
}
// Adaptee
public class CCessna
{
public void Fly()
{
Console.WriteLine("Static runup OK, we're off in our C172");
}
}
// Class Adapter
public class CDrivableCessna : CCessna, ICar
{
public void Drive() { base.Fly(); }
}
// Object Adapter
public class CDrivableCessna2 : ICar
{
private CCessna m_oContained;
public CDrivableCessna2()
{
m_oContained = new CCessna();
}
public void Drive() { m_oContained.Fly(); }
}
// Client
public class Client
{
public static void Main(string[] args)
{
ICar oCar = new CToyota();
Console.Write("Class Adapter: Driving an Automobile");
oCar.Drive();
oCar = new CDrivableCessna();
Console.Write("Driving a Cessna");
oCar.Drive();
oCar = new CDrivableCessna2();
Console.Write(" Object Adapter: Driving a Cessna");
oCar.Drive();
}
}
八、 關(guān)于Adapter模式的討論
Adapter模式在實現(xiàn)時有以下這些值得注意的地方:
1、 目標(biāo)接口可以省略,模式發(fā)生退化。但這種做法看似平庸而并不平庸,它可以使Adaptee不必實現(xiàn)不需要的方法(可以參考Default Adapter模式)。其表現(xiàn)形式就是父類實現(xiàn)缺省方法,而子類只需實現(xiàn)自己獨特的方法。這有些像模板(Template)模式。
2、 適配器類可以是抽象類。
3、 帶參數(shù)的適配器模式。使用這種辦法,適配器類可以根據(jù)參數(shù)返還一個合適的實例給客戶端。
適配器模式(Adapter):Match interfaces of different classes合成模式(Composite):A tree structure of simple and composite objects裝飾模式(Decorator):Add responsibilities to objects dynamically代理模式(Proxy):An object representing another object享元模式(Flyweight):A fine-grained instance used for efficient sharing門面模式(Facade):A single class that represents an entire subsystem橋梁模式(Bridge):Separates an object interface from its implementation
一、 適配器(Adapter)模式
適配器模式把一個類的接口變換成客戶端所期待的另一種接口,從而使原本接口不匹配而無法在一起工作的兩個類能夠在一起工作。
名稱由來
這很像變壓器(Adapter),變壓器把一種電壓變換成另一種電壓。美國的生活用電電壓是110V,而中國的電壓是220V。如果要在中國使用美國電器,就必須有一個能把220V電壓轉(zhuǎn)換成110V電壓的變壓器。這個變壓器就是一個Adapter。
Adapter模式也很像貨物的包裝過程:被包裝的貨物的真實樣子被包裝所掩蓋和改變,因此有人把這種模式叫做包裝(Wrapper)模式。事實上,大家經(jīng)常寫很多這樣的Wrapper類,把已有的一些類包裝起來,使之有能滿足需要的接口。
適配器模式的兩種形式
適配器模式有類的適配器模式和對象的適配器模式兩種。我們將分別討論這兩種Adapter模式。
二、 類的Adapter模式的結(jié)構(gòu):

由圖中可以看出,Adaptee類沒有Request方法,而客戶期待這個方法。為了使客戶能夠使用Adaptee類,提供一個中間環(huán)節(jié),即類Adapter類,Adapter類實現(xiàn)了Target接口,并繼承自Adaptee,Adapter類的Request方法重新封裝了Adaptee的SpecificRequest方法,實現(xiàn)了適配的目的。
因為Adapter與Adaptee是繼承的關(guān)系,所以這決定了這個適配器模式是類的。
該適配器模式所涉及的角色包括:
目標(biāo)(Target)角色:這是客戶所期待的接口。因為C#不支持多繼承,所以Target必須是接口,不可以是類。
源(Adaptee)角色:需要適配的類。
適配器(Adapter)角色:把源接口轉(zhuǎn)換成目標(biāo)接口。這一角色必須是類。
三、 類的Adapter模式示意性實現(xiàn):
下面的程序給出了一個類的Adapter模式的示意性的實現(xiàn):
復(fù)制代碼 代碼如下:
// Class Adapter pattern -- Structural example
using System;
// "ITarget"
interface ITarget
{
// Methods
void Request();
}
// "Adaptee"
class Adaptee
{
// Methods
public void SpecificRequest()
{
Console.WriteLine("Called SpecificRequest()" );
}
}
// "Adapter"
class Adapter : Adaptee, ITarget
{
// Implements ITarget interface
public void Request()
{
// Possibly do some data manipulation
// and then call SpecificRequest
this.SpecificRequest();
}
}
/**//// <summary>
/// Client test
/// </summary>
public class Client
{
public static void Main(string[] args)
{
// Create adapter and place a request
ITarget t = new Adapter();
t.Request();
}
}
四、 對象的Adapter模式的結(jié)構(gòu):
該適配器模式所涉及的角色包括:
目標(biāo)(Target)角色:這是客戶所期待的接口。目標(biāo)可以是具體的或抽象的類,也可以是接口。
源(Adaptee)角色:需要適配的類。
適配器(Adapter)角色:通過在內(nèi)部包裝(Wrap)一個Adaptee對象,把源接口轉(zhuǎn)換成目標(biāo)接口。
五、 對象的Adapter模式示意性實現(xiàn):
下面的程序給出了一個類的Adapter模式的示意性的實現(xiàn):
復(fù)制代碼 代碼如下:
// Adapter pattern -- Structural example
using System;
// "Target"
class Target
{
// Methods
virtual public void Request()
{
// Normal implementation goes here
}
}
// "Adapter"
class Adapter : Target
{
// Fields
private Adaptee adaptee = new Adaptee();
// Methods
override public void Request()
{
// Possibly do some data manipulation
// and then call SpecificRequest
adaptee.SpecificRequest();
}
}
// "Adaptee"
class Adaptee
{
// Methods
public void SpecificRequest()
{
Console.WriteLine("Called SpecificRequest()" );
}
}
/**//// <summary>
/// Client test
/// </summary>
public class Client
{
public static void Main(string[] args)
{
// Create adapter and place a request
Target t = new Adapter();
t.Request();
}
}
六、 在什么情況下使用適配器模式
在以下各種情況下使用適配器模式:
1、 系統(tǒng)需要使用現(xiàn)有的類,而此類的接口不符合系統(tǒng)的需要。
2、 想要建立一個可以重復(fù)使用的類,用于與一些彼此之間沒有太大關(guān)聯(lián)的一些類,包括一些可能在將來引進(jìn)的類一起工作。這些源類不一定有很復(fù)雜的接口。
3、 (對對象適配器而言)在設(shè)計里,需要改變多個已有子類的接口,如果使用類的適配器模式,就要針對每一個子類做一個適配器,而這不太實際。
七、 一個實際應(yīng)用Adapter模式的例子
下面的程序演示了Class Adapter與Object Adapter的應(yīng)用。
復(fù)制代碼 代碼如下:
// Example of implementing the Adapter pattern
using System;
// Target
public interface ICar
{
void Drive();
}
// Direct use without Adapter
public class CToyota : ICar
{
public void Drive()
{
Console.WriteLine("Vroom Vroom, we're off in our Toyota");
}
}
// Adaptee
public class CCessna
{
public void Fly()
{
Console.WriteLine("Static runup OK, we're off in our C172");
}
}
// Class Adapter
public class CDrivableCessna : CCessna, ICar
{
public void Drive() { base.Fly(); }
}
// Object Adapter
public class CDrivableCessna2 : ICar
{
private CCessna m_oContained;
public CDrivableCessna2()
{
m_oContained = new CCessna();
}
public void Drive() { m_oContained.Fly(); }
}
// Client
public class Client
{
public static void Main(string[] args)
{
ICar oCar = new CToyota();
Console.Write("Class Adapter: Driving an Automobile");
oCar.Drive();
oCar = new CDrivableCessna();
Console.Write("Driving a Cessna");
oCar.Drive();
oCar = new CDrivableCessna2();
Console.Write(" Object Adapter: Driving a Cessna");
oCar.Drive();
}
}
八、 關(guān)于Adapter模式的討論
Adapter模式在實現(xiàn)時有以下這些值得注意的地方:
1、 目標(biāo)接口可以省略,模式發(fā)生退化。但這種做法看似平庸而并不平庸,它可以使Adaptee不必實現(xiàn)不需要的方法(可以參考Default Adapter模式)。其表現(xiàn)形式就是父類實現(xiàn)缺省方法,而子類只需實現(xiàn)自己獨特的方法。這有些像模板(Template)模式。
2、 適配器類可以是抽象類。
3、 帶參數(shù)的適配器模式。使用這種辦法,適配器類可以根據(jù)參數(shù)返還一個合適的實例給客戶端。
相關(guān)文章
C#中調(diào)用SAPI實現(xiàn)語音識別的2種方法
這篇文章主要介紹了C#中調(diào)用SAPI實現(xiàn)語音識別的2種方法,本文直接給出實現(xiàn)代碼,需要的朋友可以參考下2015-06-06C#操作EXCEL DataTable轉(zhuǎn)換的實例代碼
C#操作EXCEL DataTable轉(zhuǎn)換的實例代碼,需要的朋友可以參考一下2013-04-04C#編程實現(xiàn)向并口設(shè)備發(fā)送指令、獲取并口設(shè)備的狀態(tài)
這篇文章主要介紹了C#編程實現(xiàn)向并口設(shè)備發(fā)送指令、獲取并口設(shè)備的狀態(tài),本文直接給出實例代碼,需要的朋友可以參考下2015-06-06淺談C#下winform和JS的互相調(diào)用和傳參(webbrowser)
下面小編就為大家?guī)硪黄獪\談C#下winform和JS的互相調(diào)用和傳參(webbrowser)。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2016-12-12C#實現(xiàn)在購物車系統(tǒng)中生成不重復(fù)訂單號的方法
這篇文章主要介紹了C#實現(xiàn)在購物車系統(tǒng)中生成不重復(fù)訂單號的方法,涉及C#中時間與字符串操作的相關(guān)技巧,非常簡單實用,需要的朋友可以參考下2015-05-05