適配器模式(Adepter),將一個類的接口轉換成客戶希望的另外一個接口。Adepter模式使得原本由於模式不兼容而不能一起工作的那些類,可以一起工作。
在軟件開發中,當系統的數據和行為都正確,但接口不符時,我們應該考慮用適配器模式,目的是使控制范圍之外的一個原有對象與某個接口匹配,適配器模式主要應用於希望復用一些現存的類,但是接口又與復用環境不一致的情況,比如要在需要對早起代碼復用,一些功能等應用上很有實用價值。
適配器模式UML類圖:

分析:
Target是客戶所期待的接口,目標可以是具體的或抽象的類也可以是接口;Adeptee是需要適配的類;Adepter是適配器類,通過在內部包裝一個Adeptee對象把源接口轉換成目標接口。
適配器模式實現:
[csharp]
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Adepter
{
/*
* 這是客戶所期待的接口,目標可以是具體的或抽象的類也可以是接口
*/
class Target
{
public virtual void Request()
{
Console.WriteLine("普通請求...");
}
}
/**
* 需要適配的類
*/
class Adeptee
{
public void SpecificRequest()
{
Console.WriteLine("特殊請求...");
}
}
/*
* Adepter通過在內部包裝一個Adeptee對象把源接口轉換成目標接口
*/
class Adepter : Target
{
private Adeptee adeptee = new Adeptee();//這是一個私有的Adeptee對象
public override void Request()
{
this.adeptee.SpecificRequest();//這樣就可以把表面調用Request()方法,轉換為調用SpecificRequest()方法
//base.Request();
}
}
}
客戶端:
[csharp]
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Adepter
{
class Program
{
static void Main(string[] args)
{
Target target = new Adepter();
target.Request();//對客戶來說,調用的就是Target的Request()
Console.Read();
}
}
}
適配器模式總結:
當使用一個已經存在的類,但是它的接口也就是它的方法或你的要求不相同時;兩個類所做的事情相同或者相似但是接口不同時,應該考慮使用適配器模式。這樣客戶可以統一調用一個接口,從而更簡單、更直接、更緊湊。
適配器模式案例—籃球翻譯適配器
[csharp]
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace AdepterExample
{
abstract class Player
{
private string name;
public Player(string name)
{
this.name = name;
}
public string getName()
{
return this.name;
}
public void setName(string name)
{
this.name = name;
}
public abstract void Attack();
public abstract void Defense();
}
class Forwards : Player
{
public Forwards(string name):base(name){}
public override void Attack()
{
Console.WriteLine("前鋒{0},進攻!",this.getName());
//throw new NotImplementedException();
}
public override void Defense()
{
Console.WriteLine("前鋒{0},防守!", this.getName());
//throw new NotImplementedException();
}
}
class Center : Player
{
public Center(string name) : base(name) { }
public override void Attack()
{
Console.WriteLine("中鋒{0},進攻!", this.getName());
//throw new NotImplementedException();
}
public override void Defense()
{
Console.WriteLine("中鋒{0},防守!", this.getName());
//throw new NotImplementedException();
}
}
class Guards : Player
{
public Guards(string name) : base(name) { }
public override void Attack()
{
Console.WriteLine("後衛{0},進攻!", this.getName());
//throw new NotImplementedException();
}
public override void Defense()
{
Console.WriteLine("後衛{0},防守!", this.getName());
//throw new NotImplementedException();
}
}
class ForeignCenter
{
private string name;
public string getName()
{
return this.name;
}
public void setName(string name)
{
this.name = name;
}
public void 進攻()
{
Console.WriteLine("外籍中鋒{0},進攻!", this.name);
}
public void 防守()
{
Console.WriteLine("外籍中鋒{0},防守!",this.name);
}
}
class Adepter : Player
{
private ForeignCenter foreignCenter = new ForeignCenter();
public Adepter(string name) : base(name)
{
foreignCenter.setName(name);
}
public override void Attack()
{
foreignCenter.進攻();
//throw new NotImplementedException();
}
public override void Defense()
{
foreignCenter.防守();
//throw new NotImplementedException();
}
}
}
客戶端:
[csharp]
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace AdepterExample
{
class Program
{
static void Main(string[] args)
{
Player p1 = new Forwards("巴蒂爾");
Player p2 = new Adepter("姚明");
Player p3 = new Guards("麥克格雷迪");
p1.Attack();
p2.Attack();
p3.Attack();
p2.Defense();
Console.Read();
}
}
}
運行結果: