深入浅出设计模式-007:适配器模式(Adapter Pattern)
一:用火鸡来冒充鸭子(对象适配) Client:客户认为他正在和鸭子沟通 Target: Duck,目标是鸭子类 Adaptee:Turkey,火鸡没有鸭子的方法,但是适配器可以将对鸭子方法的调用转换到调用火鸡的方法 Adapter:TurkeyAdapter。TurkeyAdapter : Duck
public interface Duck{ void quack(); void fly(); } public class MallardDuck : Duck{ public void quack(){ Console.WriteLine("MallardDuck quack"); } public void fly(){ Console.WriteLine("MallardDuck fly"); } } public interface Turkey{ void gobble(); void fly(); } public class WildTurkey : Turkey{ public void gobble(){ Console.WriteLine("WildTurkey gobble"); } public void fly(){ Console.WriteLine("WildTurkey fly"); } } //实现转成的类型接口 public class TurkeyAdapter : Duck{ Turkey turkey; //需要取得适配的对象引用 public TurkeyAdapter(Turkey turkey){ this.turkey = turkey; } public void quack(){ turkey.gobble(); } public void fly(){ turkey.fly(); } class Program { static void Main(string[] args) { //鸭子行为 MallardDuck duck = new MallardDuck(); duck.quack(); duck.fly();
//火鸡行为 WildTurkey turkey = new WildTurkey(); turkey.gobble(); turkey.fly();
//看着是鸭子,实际上是火鸡 Duck turkeyAdapter = new TurkeyAdapter(turkey); turkeyAdapter.quack(); turkeyAdapter.fly(); } }
二:适配器的使用过程 客户通过目标接口调用适配器的方法对适配器发出请求 适配器使用被适配器的接口把请求转换成被适配者的一个或多个调用接口 public void quack(){ turkey.gobble(); } public void fly(){ turkey.fly(); } 客户接收到调用的结果,但并未察觉这一切是适配器在起转换作用
三:适配器模式: 将一个类的接口,转换成客户期望的另一个接口。适配器让原本接口不兼容的类可以合作无间。
四:类的适配器模式 Client:客户认为他正在和鸭子沟通 Target: Duck,目标是鸭子类 Adaptee:Turkey,火鸡没有鸭子的方法,但是适配器可以将对鸭子方法的调用转换到调用火鸡的方法 Adapter(重点):TurkeyAdapter。TurkeyAdapter : Duck, Turkey 用一个类同时继承接口和已知类,利用已知类中定义的方法和属性等,实现接口中的定义(主要利用了重载接口方法的办法)。 public interface Duck{ void quack(); void fly(); } public class MallardDuck : Duck{ public void quack(){ Console.WriteLine("MallardDuck quack"); } } public interface Turkey{ void gobble(); } public class WildTurkey : Turkey{ public void gobble(){ Console.WriteLine("WildTurkey gobble"); } } //实现转成的类型接口 public class TurkeyAdapter : WildTurkey, Duck{ public void quack(){ gobble(); } } class Program{ static void Main(string[] args){ MallardDuck duck = new MallardDuck(); duck.quack();
WildTurkey turkey = new WildTurkey(); turkey.gobble();
Duck turkeyAdapter = new TurkeyAdapter(); turkeyAdapter.quack(); } }
五:当需要使用一个现有的类而其接口并不符合你的需要时,就使用适配器。 当需要简化并统一一个很大的接口或者一群复杂的接口时,使用外观。 适配器改变接口以符合客户的期望。 外观将客户从一个复杂的子系统中解耦。 实现一个适配器可能需要一番功夫,也可能不费功夫,视目标接口的大小与复杂度而定。 实现一个外观,需要将子系组合进外观中,然后将工作委托给子系统执行。 适配器模式的两种形式:对象适配器和类适配器。类适配器需要用到多重继承。 你可以为一个子系统实现一个以上的外观。 适配器将一个对象包装起来以改变其接口。装饰者将一个对象包装起来以增加新的行为和责任,而外观将一群对象包装起来以简化接口