在想使用一个已经存在的类,但如果它的接口,也就是它的方法和你的要求不相同时,就应该考虑用适配器模式。
两个类所做的事情相同或相似,但是具有不同的接口时要使用它。而且由于类都共享一个接口
客户代码可以统一调用同一接口就行了,这样应该可以更简单、更直接、更紧凑
static void Main(string[] args) { Target target = new Adapter(); //对客户端来说,调用的就是Target的Request() target.Request(); Console.Read(); }
class Target { public virtual void Request() { Console.WriteLine("普通请求!"); } }
class Adaptee { public void SpecificRequest() { Console.WriteLine("特殊需求!"); } }
class Adapter : Target { private Adaptee adaptee = new Adaptee(); //建立一个私有的Adaptee对象 public override void Request() { adaptee.SpecificRequest(); //这样就可以把表面上调用Request()方法变成实际调用SpecialRequest() } }
姚明去了NBA但是,当时的姚明的英语水平并不是很好,所以在与教练和队友之间需要有一个翻译来帮助他理解。
abstract class Player { protected string name; public Player(string name) { this.name = name; } public abstract void Attack(); //进攻的方法 public abstract void Defence(); //防守的方法 }
class Forwards : Player { public Forwards(string name) : base(name) { } public override void Attack() { Console.WriteLine("前锋{0} 进攻",name); } public override void Defence() { Console.WriteLine("前锋{0} 防守", name); } }
class Center : Player { public Center(string name) : base(name) { } public override void Attack() { Console.WriteLine("中锋{0} 进攻", name); } public override void Defence() { Console.WriteLine("中锋{0} 防守", name); } }
class Guards : Player { public Guards(string name) : base(name) { } public override void Attack() { Console.WriteLine("后卫{0} 进攻", name); } public override void Defence() { Console.WriteLine("后卫{0} 防守", name); } }
static void Main(string[] args) { Player b = new Forwards("巴蒂尔"); b.Attack(); Player m = new Guards("麦克格雷迪"); m.Attack(); Player ym = new Center("姚明"); ym.Attack(); //姚明问;“Attack”和“Defence”是什么意思 ym.Defence(); Console.Read(); }
1 通过适配器,客户端可以调用同一接口,因而对客户端来说是透明的。这样做更简单、更直接、更紧凑。
2 复用了现存的类,解决了现存类和复用环境要求不一致的问题。
3 将目标类和适配者类解耦,通过引入一个适配器类重用现有的适配者类,而无需修改原有代码。
4 一个对象适配器可以把多个不同的适配者类适配到同一个目标,也就是说,同一个适配器可以把适配者类和它的子类都适配到目标接口。
缺点:
对于对象适配器来说,更换适配器的实现过程比较复杂。
1.系统需要使用一些现有的类,而这些类的接口不符合系统的需要,甚至美誉这些类的源代码
2.创建一个可以重复使用的类,用于和一些彼此之间没有太大关联的类,包括一些可能在将来引进的类一起工作
适配器模式不可不用,也不可过度使用。如果能事先预防接口不同的问题,不匹配问题就不会发生;在有小的接口不统一的问题发生时,及时重构,问题不至于扩大;只有碰到无法改变原有设计和代码的情况时,才考虑适配。事后控制不如事中控制,事中控制不如事前控制。