动机:
在软件系统中,由于应用环境的变化,常常需要将“一些现存的对象”放在新的环境中应用,但是新环境要求的接口是这些现存对象所不满足的。
如何应对这种“迁移的变化”?如何既能利用现有对象的良好实现,同时又能满足新的应用环境所要求的接口?
意图:
将一个类的接口转换成客房希望的另一个接口。Adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。
出自:《设计模式》GoF
Adapter模式的几个要点:
1、Adapter模式主要应用于“希望复用一些现存的类,但是接口又与复用的环境要求不一致的情况”,在遗留代码复用、类库迁移等方面非常有用。
2、GoF23定义了两种Adapter模式的实现结构:对象适配器采用“对象组合”的方式,更符合松耦合精神。
3、Adapter模式可以实现的非常灵活,不必拘泥于GoF23中定义的两种结构。例如,完全可以将Adapter模式中的“现存对象”作为新的接口方法参数,来达到适配的目的。
4、Adapter模式本身要求我们尽可能地使用“面向接口的编程”风格,这样才能在后期很方便地适配。
稳定部分:
interface Istack // 客户期望的接口,这里被适配的对象是一个ArrayList对象
{
public void Push(object item);
public object Pop();
public object Peek();
}
{
public void Push(object item);
public object Pop();
public object Peek();
}
变化部分:
//对象适配器(推荐使用)
class AdapterA: Istack //适配对象
{
ArrayList adpatee; //被适配的对象
public AdapterA()
{
}
public void Push(object item)
{
adpatee.Add(item);
}
public object Pop()
{
return adpatee.RemoveAt(adpatee.Count - 1);
}
public object Peek()
{
return adpatee[adpatee.Count - 1];
}
}
//类适配器
class AdapterB: ArrayList,Istack //适配对象
{
public AdapterB()
{
}
public void Push(object item)
{
this.Add(item);
}
public object Pop()
{
return this.RemoveAt(this.Count - 1);
}
public object Peek()
{
return this[this.Count - 1];
}
}
class AdapterA: Istack //适配对象
{
ArrayList adpatee; //被适配的对象
public AdapterA()
{
}
public void Push(object item)
{
adpatee.Add(item);
}
public object Pop()
{
return adpatee.RemoveAt(adpatee.Count - 1);
}
public object Peek()
{
return adpatee[adpatee.Count - 1];
}
}
//类适配器
class AdapterB: ArrayList,Istack //适配对象
{
public AdapterB()
{
}
public void Push(object item)
{
this.Add(item);
}
public object Pop()
{
return this.RemoveAt(this.Count - 1);
}
public object Peek()
{
return this[this.Count - 1];
}
}
主程序:
//对象适配器优于类适配器
public static void Main()
{
AdapterA a = new AdapterA();
a.Pop();
a.Push(item);
a.Peek();
AdapterB b = new AdapterB();
b.Pop();
b.Push(item);
b.Peek();
}
public static void Main()
{
AdapterA a = new AdapterA();
a.Pop();
a.Push(item);
a.Peek();
AdapterB b = new AdapterB();
b.Pop();
b.Push(item);
b.Peek();
}