名稱 |
Adapter
|
結構 |
? |
意圖 |
將一個類的接口轉換成客戶希望的另外一個接口。A d a p t e r 模式使得原本由于接口不兼容而不能一起工作的那些類可以一起工作。 |
適用性 |
- 你想使用一個已經存在的類,而它的接口不符合你的需求。
- 你想創建一個可以復用的類,該類可以與其他不相關的類或不可預見的類(即那些接口可能不一定兼容的類)協同工作。
- (僅適用于對象A d a p t e r )你想使用一些已經存在的子類,但是不可能對每一個都進行子類化以匹配它們的接口。對象適配器可以適配它的父類接口。
|
|
|
Code Example
OurAdapter聚集了FrameworkXTraget 和FrameworkYTarget的功能.
namespace?Adapter_DesignPattern


{
????using?System;

????class?FrameworkXTarget?

????
{
????????virtual?public?void?SomeRequest(int?x)

????????
{
????????????//?normal?implementation?of?SomeRequest?goes?here????????????????????
????????}
????}

????class?FrameworkYAdaptee

????
{
????????public?void?QuiteADifferentRequest(string?str)?

????????
{
????????????Console.WriteLine("QuiteADifferentRequest?=?{0}",?str);
????????}????????
????}

????class?OurAdapter?:?FrameworkXTarget

????
{
????????private?FrameworkYAdaptee?adaptee?=?new?FrameworkYAdaptee();
????????override?public?void?SomeRequest(int?a)

????????
{
????????????string?b;
????????????b?=?a.ToString();
????????????adaptee.QuiteADifferentRequest(b);
????????}????????
????}


????/**////?<summary>
????///????Summary?description?for?Client.
????///?</summary>
????public?class?Client

????
{
????????void?GenericClientCode(FrameworkXTarget?x)

????????
{
????????????//?We?assume?this?function?contains?client-side?code?that?only?
????????????//?knows?about?FrameworkXTarget.
????????????x.SomeRequest(4);
????????????//?other?calls?to?FrameworkX?go?here
????????????//?
????????}
????????
????????public?static?int?Main(string[]?args)

????????
{
????????????Client?c?=?new?Client();
????????????FrameworkXTarget?x?=?new?OurAdapter();
????????????c.GenericClientCode(x);????
????????????return?0;
????????}
????}
}

通過繼承Target和成員Adaptee 的適配方式,使Adapter 最終滿足我們的需要!
//?Adapter?pattern?--?Structural?example??


using?System;

namespace?DoFactory.GangOfFour.Adapter.Structural


{

??//?Mainapp?test?application?

??class?MainApp

??
{
????static?void?Main()

????
{
??????//?Create?adapter?and?place?a?request?
??????Target?target?=?new?Adapter();
??????target.Request();

??????//?Wait?for?user?
??????Console.Read();
????}
??}

??//?"Target"?

??class?Target

??
{
????public?virtual?void?Request()

????
{
??????Console.WriteLine("Called?Target?Request()");
????}
??}

??//?"Adapter"?

??class?Adapter?:?Target

??
{
????private?Adaptee?adaptee?=?new?Adaptee();

????public?override?void?Request()

????
{
??????//?Possibly?do?some?other?work?
??????//?and?then?call?SpecificRequest?
??????adaptee.SpecificRequest();
????}
??}

??//?"Adaptee"?

??class?Adaptee

??
{
????public?void?SpecificRequest()

????
{
??????Console.WriteLine("Called?SpecificRequest()");
????}
??}
}
?

上面例子可以認為是
對象的Adapter模式, 因為target為一個實際的類,不是一個接口
以下為
類的Adapter設計模式: 因為target 為一個接口,又接口規范,且沒有實例成員
//??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();
??}
} 總結: 類適配器比對象適配器更好
???????? 類適配器提供了接口規范,
???????? 但是對象適配器沒有,如果target改變接口的話,adaper可能沒有跟著改變,最后導致error.也又可能會錯用target里的實例成員.