更多关于设计模式的文章请点击:设计模式之禅(0)-目录页
适配器模式是面向对象设计模式中常用的一种模式,它能将一个类的接口转换成用户希望的另一个接口,让原本不兼容的程序接口能够相互协作。
一、适配器模式是什么
**适配器模式(Adapter Pattern
)**的定义是: 将一个类的接口适配成用户所期待的。一个适配允许通常因为接口不兼容而不能在一起工作的类工作在一起,做法是将类自己的接口包裹在一个已存在的类中。
二、把鸭子“适配”为狗
又要以我们可爱的动物园动物作为栗子了。本次我要做的是将鸭子接口通过适配器的方式适配为狗接口:
- Duck
/**
* @Description: Duck接口
* @CreateDate: Created in 2018/11/28 20:35
* @Author: <a href="https://blog.youkuaiyun.com/pbrlovejava">arong</a>
*/
public interface Duck {
//鸭子叫
public void duckCall();
}
- Dog
/**
* @Description: Dog接口
* @CreateDate: Created in 2018/11/28 20:32
* @Author: <a href="https://blog.youkuaiyun.com/pbrlovejava">arong</a>
*/
public interface Dog {
//犬吠
public void DogCall();
}
- WildDuck
/**
* @Description: Duck的实现类
* @CreateDate: Created in 2018/11/28 20:37
* @Author: <a href="https://blog.youkuaiyun.com/pbrlovejava">arong</a>
*/
public class WildDuck implements Duck {
@Override
public void duckCall() {
System.out.println("鸭子叫哒哒哒");
}
}
- DuckToDogAdapter
/**
* @Description: Duck接口转换成Dog接口的适配器
* @CreateDate: Created in 2018/11/28 20:34
* @Author: <a href="https://blog.youkuaiyun.com/pbrlovejava">arong</a>
*/
public class DuckToDogAdapter implements Dog{
private Duck duck;
public DuckToDogAdapter(Duck duck){
this.duck = duck;//对象组合
}
@Override
public void DogCall() {
//适配器将狗叫转换成了鸭子叫
duck.duckCall();
}
}
- Client
/**
* @Description: 调用狗接口的客户类
* @CreateDate: Created in 2018/11/28 20:40
* @Author: <a href="https://blog.youkuaiyun.com/pbrlovejava">arong</a>
*/
public class Client {
public static void TestDog(Dog dog){
dog.DogCall();
}
}
以上就是适配器模式的简单栗子,现在通过测试类去测试它:
- TestAdapterPattern
/**
* @Description: 测试适配器模式 Dog-》Duck
* @CreateDate: Created in 2018/11/28 20:41
* @Author: <a href="https://blog.youkuaiyun.com/pbrlovejava">arong</a>
*/
public class TestAdapterPattern {
@Test
public void testDogToDuck(){
//创建野鸭子对象
WildDuck duck = new WildDuck();
//创建适配器对象,用适配器将鸭子转化为狗
DuckToDogAdapter adapter = new DuckToDogAdapter(duck);
//调用客户端测试
Client.TestDog(adapter);
}
}
运行结果:
三、把枚举接口适配为迭代器接口
1.类适配器模式
在类适配器模式中,适配器类(Adapter)实现了目标接口(Target)并继承了适配者类(Adaptee),并在目标接口的重写实现方法中调用所继承的适配者类的方法,例如以下的EIAdapter采用了类适配器模式,将枚举类(Adaptee)的方法适配为迭代器接口(Target)的方法:
- MyEnumeration
/**
* @Auther: ARong
* @Description: 自定义枚举类
*/
public class MyEnumeration implements Enumeration {
@Override
public boolean hasMoreElements() {
return false;
}
@Override
public Object nextElement() {
return null;
}
}
public interface Iterator<E> {
default void remove() {
throw new UnsupportedOperationException("remove");
}
boolean hasNext();
E next();
}
- EIAdapter
/**
* @Auther: ARong
* @Description: 类适配器模式-将自定义的枚举类适配为迭代器接口
*/
public class EIAdapter extends MyEnumeration implements Iterator {
@Override
public boolean hasNext() {
return super.hasMoreElements();
}
@Override
public Object next() {
return super.nextElement();
}
@Override
public void remove() {
// 由于自定义枚举类中不存在这个方法,所以这里需要自己实现具体的逻辑,去适配迭代器接口
}
}
2.对象适配器模式
在对象适配器模式中,适配器类(Adapter)实现了目标接口(Target)并且组合来适配者类或接口(Adaptee),并在目标接口的重写实现方法中调用所组合的适配者类或接口的方法,例如以下的EIAdapter采用了类适配器模式,将枚举类(Adaptee)的方法适配为迭代器接口(Target)的方法:
- EIAdapter
/**
* @Auther: ARong
* @Description: 对象适配器模式
*/
public class EIAdapter implements Iterator {
// 组合枚举接口
private Enumeration enumeration;
public EIAdapter(Enumeration enumeration) {
this.enumeration = enumeration;
}
@Override
public boolean hasNext() {
return enumeration.hasMoreElements();
}
@Override
public Object next() {
return enumeration.nextElement();
}
@Override
public void remove() {
// 自定义逻辑
}
}