介绍:适配器模式是将一个类的接口转换成用户希望的另一种接口
最好的例子就是笔记本电脑的电源适配器,家用的电源是220v的而电脑承受不了这么高的电压,假设他可以承受15v的电压,怎么办呢 ,我们不能把家里的电压变成15v,也不能把电脑的电压提高到220v,最好的办法就是我们需要用一个东西转换他,把220v的电压转换成15v,这个东西就是适配器
在实际应用的条件下,系统提供的数据和行为都是正确的,但是我们要用用不了,原因是接口不符合要求,这时候我们需要一个适配器,将这个接口不符合的数据和行为利用起来,这样我们不至于去修改大量的代码,而完成这个要求,提高了代码的复用性。
把适配器分为两种:类适配器和接口适配器
类适配器模式
-- 这种适配器模式下,适配器继承自已实现的类(一般多重继承)。
对象适配器模式
-- 在这种适配器模式中,适配器容纳一个它包裹的类的实例。在这种情况下,适配器调用被包裹对象的物理实体。
类适配器:
首先要有一个目标接口或者是目标类package demo_adapter; public interface Target { public abstract void function1(); public abstract void function2(); }
还有一个源类,这个类中只有一个function1方法,没有function2方法
package demo_adapter; public class Adaptee { public void function1() { System.out.println("Adaptee的function1方法"); } }
在Adaptee类中,只有function2方法,但是目标接口要求有两个方法,我们需要一个适配器类Adapter,在继承Adaptee的同时实现了目标接口,这样既提高了代码的复用性,还扩展了Adaptee类。
package demo_adapter; public class Adapter extends Adaptee implements Target { @Override public void function2() { System.out.println("Adapter的function2方法"); } }用户类:
package demo_adapter; public class Client { public static void main(String[] args) { Target target = new Adapter(); target.function1(); target.function2(); } }输出:
Adaptee的function1方法 Adapter的function2方法
对象适配器:
和类适配器一样最终都是代码的复用。适配器类中包裹着一个源类的对象,用这个对象调用源类中已经拥有的方法
一个目标类中提供两个方法function1,function2:
package demo_adapter1; public interface Target { public abstract void function1(); public abstract void function2(); }
源类依旧缺少function2方法:
package demo_adapter1; public class Adaptee { public void function1() { System.out.println("Aaptee的function1方法"); } }
适配器类:
提供一个源类的对象,,用这个对象来调用源类的方法,或者说是委派给源类,不需要适配器类做什么具体的操作
package demo_adapter1; public class Adapter implements Target { private Adaptee adpaptee; public Adapter(Adaptee adpaptee) { this.adpaptee = adpaptee; } public void function1() { this.adpaptee.function1(); } public void function2() { System.out.println("Adapter的function2方法"); } }
用户类:
package demo_adapter1; public class Client { public static void main(String[] args) { Adaptee a = new Adaptee(); Adapter adapter = new Adapter(a); adapter.function1(); adapter.function2(); } }
输出:
Adaptee的function1方法 Adapter的function2方法输出结果表示调用的function1方法是Adaptee类的,function2方法是Adapter类的
对于这两个适配器的选择,最适合的就是最合适的。哪个适合当前条件就用哪个。
适配器模式的优点:提高了代码的复用性,让原本不适合使用的代码通过适配利用起来,增加了扩展性,在使用原代码的同时可以增加自己的方法。
适配器模式的缺点:在使用适配器模式的时候,定义了好多适配器,原本的接口被适配成了别的借口,可能后期维护起来不方便。
看到别的文章还有一种缺省适配器,但是在介绍适配器的时候这个缺省适配器不再适配器模式的类型里面,个人认为这个还是很好理解的。同样也是有一个目标接口,我们可能不需要这么多的方法,怎么办呢?用一个类实现这个接口,要实现接口,必须实现接口中的所有方法,当用户向用这些方法的时候,用类去继承这个实现所有方法的类。
目标类:
package demo_default; public interface Target { public abstract void study(); public abstract void play(); public abstract void eat(); public abstract void sleep(); }目标类中有学,玩,吃,睡方法,我们只想玩,吃,睡
package demo_default; public class OnePeople implements Target { @Override public void study() { System.out.println("学"); } @Override public void play() { System.out.println("玩"); } @Override public void eat() { System.out.println("吃"); } @Override public void sleep() { System.out.println("睡"); } }经过适配器,我们只需要吃睡玩就行了
package demo_default; public class We extends OnePeople { @Override public void eat() { super.eat(); } @Override public void play() { super.play(); } @Override public void sleep() { super.sleep(); } }
另一种缺省适配器的实现方式,用一个抽象类实现接口中的部分方法,在用一个类去继承这个抽象类,对其中的方法进行重写。