原理或定義
适配器就是一种适配中间件,它存在于不匹配的二者之间,用于连接二者,将不匹配变得匹配,简单点理解就是平常所见的转接头,转换器之类的存在。
将一类的接口转换成客户希望的另外一个接口,Adapter模式使得原本由于接口不兼容而不能一起工作那些类可以一起工作。
结构
目标接口(Target): 客户所期待的接口。目标可以是具体的或抽象的类,也可以是接口。
需要适配的类(Adaptee): 需要适配的类或适配者类。
适配器(Adapter): 通过包装一个需要适配的对象,把原接口转换成目标接口。
分類
1) 类适配器
当客户在接口中定义了他期望的行为时,我们就可以应用适配器模式,提供一个实现该接口的类,并且扩展已有的类,通过创建子类来实现适配。
2)对象适配器 (推薦使用)
对象适配器通过组合除了满足"用户期待的接口"还降低了代码间的不良耦合。
3)缺省适配器
缺省适配器模式是一种特殊的适配器模式,但这个适配器是由一个抽象类实现的,并且在抽象类中要实现目标接口中所规定的所有方法,但很多方法的实现都是空方法,而具体的子类都要继承此抽象类。
類圖
案例与代碼
本模式用火鸡冒充鸭子的案例来做示例
类适配器解决方案:
类图:
鸭子接口:
public interface Duck {
public void quack();
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 Turkey {
public void gobble();
public void 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 class TurkeyAdapter 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 MainTest {
public static void main(String[] args) {
Duck duck2turkeyAdapter=new TurkeyAdapter();
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();
}
}
}
对象适配器和类适配器使用了不同的方法实现适配,对象适配器使用组合,类适配器使用继承。
使用場景
类适配器与对象适配器的使用场景一致,二者主要用于如下场景:
(1)想要使用一个已经存在的类,但是它却不符合现有的接口规范,导致无法直接去访问,这时创建一个适配器就能间接去访问这个类中的方法。
(2)我们有一个类,想将其设计为可重用的类(可被多处访问),我们可以创建适配器来将这个类来适配其他没有提供合适接口的类。
接口适配器使用场景:
(1)想要使用接口中的某个或某些方法,但是接口中有太多方法,我们要使用时必须实现接口并实现其中的所有方法,可以使用抽象类来实现接口,并不对方法进行实现(仅置空),然后我们再继承这个抽象类来通过重写想用的方法的方式来实现。这个抽象类就是适配器。
接口適配器代碼
目标接口:A
public interface A {
void a();
void b();
void c();
void d();
void e();
void f();
}
适配器:Adapter
public abstract class Adapter implements A {
public void a(){}
public void b(){}
public void c(){}
public void d(){}
public void e(){}
public void f(){}
}
实现类:Ashili
public class Ashili extends Adapter {
public void a(){
System.out.println("实现A方法被调用");
}
public void d(){
System.out.println("实现d方法被调用");
}
}