1、概述
将一个类的接口转换成客户希望的另外一个接口。Adapter模式让原本接口不兼容的类合作无间。
2、结构
适配器模式有类的适配器模式和对象的适配器模式两种不同的形式。
由于类适配器模式需要用到多继承,而java并不支持多继承,下面主要说下对象适配器模式。
对象适配器的类图:
3、实例
鸭子类
public interface Duck {
void quack();
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 interface Turkey {
void gobble();
void fly();
}
火鸡子类
public class WildTurkey implements Turkey {
@Override
public void gobble() {
System.out.println("gobble");
}
@Override
public void fly() {
System.out.println("I'm flying a short distance");
}
}
现在需要拿一些火鸡对象来冒充鸭子,因为 火鸡的接口不同,显而易见不能直接拿火鸡的接口来用。
因此,需要一个适配器:
public class TurkeyAdapter implements Duck {
Turkey turkey;
public TurkeyAdapter(Turkey turkey) {
this.turkey = turkey;
}
@Override
public void quack() {
turkey.gobble();
}
@Override
public void fly() {
turkey.fly();
}
}
测试代码:
public class DuckTest {
public static void main(String[] args) {
MallardDuck duck = new MallardDuck();
WildTurkey turkey = new WildTurkey();
TurkeyAdapter adapter = new TurkeyAdapter(turkey);
System.out.println("Turkey says....");
turkey.gobble();
turkey.fly();
System.out.println("Duck says....");
testDuck(duck);
System.out.println("TurkeyAdapter says....");
testDuck(adapter);
}
public static void testDuck(Duck duck) {
duck.quack();
duck.fly();
}
}
结果:
Turkey says....
gobble
I'm flying a short distance
Duck says....
Quack
I'm flying
TurkeyAdapter says....
gobble
I'm flying a short distance
结果显示我们完美的把火鸡冒充成鸭子了。
优点:
1、让客户从实习的接口解耦,如果在一段时间之后,我们想要改变接口,适配器可以将改变的部分封装起来,客户不必为了应对不同的接口而每次跟着修改。
2、被适配器者的任何子类,都可以搭配着适配器使用。
3、更好的复用性。系统需要使用现有的类,而此类的接口不符合系统的需要。那么通过适配器模式就可以让这些功能得到更好的复用。
4、更好的扩展性。在实现适配器功能的时候,可以调用自己开发的功能,从而自然地扩展系统的功能。
缺点:
1、过多的使用适配器,会让系统非常零乱,不易整体进行把握。比如,明明看到调用的是A接口,其实内部被适配成了B接口的实现,一个系统如果太多出现这种情况,无异于一场灾难。因此如果不是很有必要,可以不使用适配器,而是直接对系统进行重构。
2、对于对象适配器来说,更换适配器的实现过程比较复杂。