一、适配器模式原理
首先,举个例子:插座与插头。比如,中国人去英联邦国家,要带插座转换器。
然后,来一段火鸡变鸭子的代码。要实现的目标是,调用鸭子类的(quack()和fly())方法,但打印火鸡的叫声和飞行距离。即,为火鸡披上鸭子的外衣,但仍然可以做自己的事情。
适配器类
public class TurkeyAdapter2 extends WildTurkey implements Duck {
@Override
public void quack() {
// TODO Auto-generated method stub
super.gobble();
}
@Override
public void fly() {
// TODO Auto-generated method stub
super.fly();
super.fly();
super.fly();
}
}
火鸡实现类
public class WildTurkey implements Turkey {
@Override
public void gobble() {
// TODO Auto-generated method stub
System.out.println(" Go Go");
}
@Override
public void fly() {
// TODO Auto-generated method stub
System.out.println("I am flying a short distance");
}
}
火鸡超类
public interface Turkey {
public void gobble();
public void fly();
}
鸭子实现类
public class GreenHeadDuck implements Duck {
@Override
public void quack() {
// TODO Auto-generated method stub
System.out.println(" Ga Ga");
}
@Override
public void fly() {
// TODO Auto-generated method stub
System.out.println("I am flying a long distance");
}
}
鸭子超类
public interface Duck {
public void quack();
public void fly();
}
测试类
public class MainTest {
public static void main(String[] args) {
GreenHeadDuck duck = new GreenHeadDuck();
WildTurkey turkey = new WildTurkey();
Duck duck2turkeyAdapter = new TurkeyAdapter2();
turkey.gobble();
turkey.fly();
duck.quack();
duck.fly();
duck2turkeyAdapter.quack();
duck2turkeyAdapter.fly();
}
}
测试结果打印:
Go Go
I am flying a short distance
Ga Ga
I am flying a long distance
Go Go
I am flying a short distance
I am flying a short distance
I am flying a short distance
可见,duck2turkeyAdapter.quack(); 和 duck2turkeyAdapter.fly();方法的调用,实现了让火鸡披着鸭子的外衣,发出了自己的叫声,实现了自己的飞行。
小结:适配器模式的核心是编写适配器,该适配器,会继承需要伪装的类(火鸡)并实现伪装供应类(鸭子)的接口方法,从而可以在重写了的供应类的方法中,编写需要伪装的类的方法。
二、对象适配器与类适配器
以下为类适配器
public class TurkeyAdapter implements Duck {
private Turkey turkey;
public TurkeyAdapter(Turkey turkey)
{
this.turkey=turkey;
}
@Override
public void quack() {
// TODO Auto-generated method stub
turkey.gobble();
}
@Override
public void fly() {
// TODO Auto-generated method stub
for(int i=0;i<6;i++)
{
turkey.fly();
}
}
}
而对象适配器使用的是组合继承方式。即,对象适配器既有继承又有实现(继承一个类+实现一个接口)。
public class TurkeyAdapter2 extends WildTurkey implements Duck {
@Override
public void quack() {
// TODO Auto-generated method stub
super.gobble();
}
@Override
public void fly() {
// TODO Auto-generated method stub
super.fly();
super.fly();
super.fly();
}
}
三、 适配器使用原则
原则上使用对象适配器(组合继承方式),尽量不要使用类适配器(类继承方式)。
四、装饰者模式与适配器模式的区别
主要在功能上,装饰者模式主要是为了增强被装饰者的能力,属于锦上添花。
适配器模式主要是为了适配,属于明修栈道,暗度陈仓。