程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> 關於C# >> C#設計模式之適配器設計模式(Adapter)

C#設計模式之適配器設計模式(Adapter)

編輯:關於C#

結構模式(Structural Pattern)描述如何將類或者對象結合在一起形成更大的結構。結構模式描述兩種不同的東西:類與類的實例。根據這一點,結構模式可以分為類的結構模式和對象的結構模式。

後續內容將包括以下結構模式:

適配器模式(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電壓轉換成110V電壓的變壓器。這個變壓器就是一個Adapter。

Adapter模式也很像貨物的包裝過程:被包裝的貨物的真實樣子被包裝所掩蓋和改變,因此有人把這種模式叫做包裝(Wrapper)模式。事實上,大家經常寫很多這樣的Wrapper類,把已有的一些類包裝起來,使之有能滿足需要的接口。

適配器模式的兩種形式

適配器模式有類的適配器模式和對象的適配器模式兩種。我們將分別討論這兩種Adapter模式。

二、類的Adapter模式的結構:

由圖中可以看出,Adaptee類沒有Request方法,而客戶期待這個方法。為了使客戶能夠使用Adaptee類,提供一個中間環節,即類Adapter類,Adapter類實現了Target接口,並繼承自Adaptee,Adapter類的Request方法重新封裝了Adaptee的SpecificRequest方法,實現了適配的目的。

因為Adapter與Adaptee是繼承的關系,所以這決定了這個適配器模式是類的。

該適配器模式所涉及的角色包括:

目標(Target)角色:這是客戶所期待的接口。因為C#不支持多繼承,所以Target必須是接口,不可以是類。

源(Adaptee)角色:需要適配的類。

適配器(Adapter)角色:把源接口轉換成目標接口。這一角色必須是類。

三、類的Adapter模式示意性實現:

下面的程序給出了一個類的Adapter模式的示意性的實現:

// 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模式的結構:

從圖中可以看出:客戶端需要調用Request方法,而Adaptee沒有該方法,為了使客戶端能夠使用Adaptee類,需要提供一個包裝(Wrapper)類Adapter。這個包裝類包裝了一個Adaptee的實例,從而將客戶端與Adaptee銜接起來。由於Adapter與Adaptee是委派關系,這決定了這個適配器模式是對象的。

該適配器模式所涉及的角色包括:

目標(Target)角色:這是客戶所期待的接口。目標可以是具體的或抽象的類,也可以是接口。

源(Adaptee)角色:需要適配的類。

適配器(Adapter)角色:通過在內部包裝(Wrap)一個Adaptee對象,把源接口轉換成目標接口。

五、對象的Adapter模式示意性實現:

下面的程序給出了一個類的Adapter模式的示意性的實現:

// 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、系統需要使用現有的類,而此類的接口不符合系統的需要。

2、想要建立一個可以重復使用的類,用於與一些彼此之間沒有太大關聯的一些類,包括一些可能在將來引進的類一起工作。這些源類不一定有很復雜的接口。

3、(對對象適配器而言)在設計裡,需要改變多個已有子類的接口,如果使用類的適配器模式,就要針對每一個子類做一個適配器,而這不太實際。

七、一個實際應用Adapter模式的例子

下面的程序演示了Class Adapter與Object Adapter的應用。

// 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();
 }
}

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved