适配器模式
1.定义
将一个类的接口,转换成客户期望的另一个接口.适配器让原本接口不兼容的类可以合作无间.
适配器可以实现目标接口,让他 " is a "目标接口,然后在目标接口具体的方法中通过组合的方式来让被适配者组合进来,在方法中调用被适配者的方法.
2.代码实现
以鸭子和火鸡为例子,比如我们想要一只鸭子,但是因为鸭子放假了,只有火鸡在,所以我们可以给火鸡装饰一层鸭子皮,让它看起来像鸭子
定义鸭子和火鸡接口
public interface Duck { void quack(); void fly(); }
public interface Turkey { public void gobble(); public void fly(); }
实现我们的绿头鸭和街头顽禽---火鸡
public class MallardDuck implements Duck { @Override public void quack() { System.out.println("Quack"); } @Override public void fly() { System.out.println("I'm flying"); } }
public class WildTurkey implements Turkey{ @Override public void gobble() { System.out.println("Gobble goobble"); } @Override public void fly() { System.out.println("I'm flying a short distance"); } }
这边绿头鸭会quack叫,并且会飞,但是火鸡gobble叫,不会飞
接下来就到了定义我们的适配器了,为了让适配器看起来像一个鸭子,所以我们的适配器需要实现目标接口---duck,因为需要装饰的对象是火鸡,所以需要把火鸡---turkey组合到适配器中
public class TurkeyAdapter implements Duck { private Turkey turkey; public TurkeyAdapter(Turkey turkey) { super(); this.turkey = turkey; } @Override public void quack() { turkey.gobble(); } @Override public void fly() { turkey.fly(); } }
我们可以自由调用火鸡的方法或者组合别的方法来实现自己想要的效果
测试类
public class DuckTestDriver { public static void main(String[] args) { MallardDuck duck = new MallardDuck(); WildTurkey turkey = new WildTurkey(); Duck turkeyAdapter = new TurkeyAdapter(turkey); System.out.println("The Turkey says..."); turkey.gobble(); turkey.fly(); System.out.println("\nThe Duck says..."); testDuck(duck); System.out.println("\nThe TurkeyAdapter says..."); testDuck(turkeyAdapter); } static void testDuck(Duck duck) { duck.quack(); duck.fly(); } }
3.总结
因为组合的接口,所以我们可以适配装饰接口的任何子类,这种通过接口实现加组合的方式来实现的适配器是对象适配器,与此相对应的还有类适配器,但是java只有单继承,所以类适配器在此不做多讨论,可以通过c++等语言实现.
虽然经常用到了装饰这个词,但是和装饰者不同的事,适配器只是做接口转换,而装饰者是添加功能和责任,两者虽然都是通过组合实现,但是目的不一样,而且具体的实现也不相同,两者还是有很大区别的.