目录
什么是适配器模式
适配器模式的实现
适配器模式角色
类适配器类图
类适配器代码实现
对象适配器类图
对象适配器代码实现
接口适配器类图
接口适配器代码实现
适配器模式的特点
优点
缺点
注意事项
使用场景
和其他模式的对比
适配器模式(Adapter)其别名为包装器模式(Wrapper),将一个类的接口适配成用户所期待的。一个适配允许通常因为接口不兼容而不能在一起工作的类工作在一起,做法是将类自己的接口包裹在一个已存在的类中。
在适配器模式中,通过增加一个新的适配器类来解决接口不兼容的问题,使得原本没有任何关系的类可以协同工作。
根据适配器类与适配者类的关系不同,适配器模式可分为对象适配器、类适配器、接口适配器三种。
举例说明:当你需要给手机充电,但是墙上只有三叉口的插座,这时候,就需要用到三叉口插排,插排上有二叉口,这是就能给手机充电了,插排就起到了一个适配器的作用。
类适配器
释义:类适配器提供一个实现该接口的类,并且扩展已有的类,通过创建子类来实现适配。
优点:可以根据需求重写Adaptee类的方法,使得Adapter的灵活性增强了。
缺点:有一定局限性。因为类适配器需要继承Target类,而Java是单继承机制,所以要求Adaptee类必须是接口。
对象适配器
释义:对象适配器”通过组合除了满足“用户期待接口”还降低了代码间的不良耦合。在工作中推荐使用“对象适配”。
优点:同一个Adapter可以把Adaptee类和他的子类都适配到目标接口。
缺点:需要重新定义Adaptee行为时,需要重新定义Adaptee的子类,并将适配器组合适配。
接口适配器
释义:接口适配器借助中间抽象类空实现目标接口所有方法,子类选择性重写,可以减少实现不必要方法。
优点:可以灵活方便的选择性重写接口方法。
缺点:由于是匿名内部类的形式,所以不利于代码复用。
从上图可以看出,Adaptee类并没有operation2()方法,而客户端则期待这个方法。为使客户端能够使用Adaptee类,需要提供一个包装(Wrapper)类Adapter。这个包装类包装了一个Adaptee的实例,从而此包装类能够把Adaptee的API与Target类的API衔接起来。Adapter与Adaptee是委派关系,这决定了适配器模式是对象的。
/**
* @author Evan Walker 昂焱数据: https://www.ayshuju.com
* @version 1.0
* @desc 类适配器
* @date 2023/06/07 14:39:18
*/
class Adaptee{//源角色
public void operation1(){
System.out.println("这是原来的类,里面存在operation1");
}
}
interface Target{//目标接口
void operation1();
void operation2();
}
class Adapter extends Adaptee implements Target{//适配器类
@Override
public void operation2() {
System.out.println("这是接口中的方法。");
}
}
public class Test {
public static void main(String[] args) {
Target adapter = new Adapter();
adapter.operation1();
adapter.operation2();
}
}
运行结果如下:
从上图可以看出,Adaptee类并没有operation2()方法,而客户端则期待这个方法。为使客户端能够使用Adaptee类,需要提供一个包装(Wrapper)类Adapter。这个包装类包装了一个Adaptee的实例,从而此包装类能够把Adaptee的API与Target类的API衔接起来。Adapter与Adaptee是委派关系,这决定了适配器模式是对象的。
/**
* @author Evan Walker 昂焱数据: https://www.ayshuju.com
* @version 1.0
* @desc 对象适配器
* @date 2023/06/07 14:39:18
*/
/**
* 目标接口
*/
interface Target {
void operation1();
void operation2();
}
/**
* 源角色
*/
class Adaptee {
public void operation1() {
System.out.println("这是原来的类,里面存在operation1");
}
}
/**
* 适配器角色
*/
class Adapter implements Target{
private Adaptee adaptee;
public Adapter(Adaptee adaptee) {
this.adaptee = adaptee;
}
/**
* 源类Adaptee有方法operation1
* 因此适配器类直接委派即可
*/
@Override
public void operation1() {
this.adaptee.operation1();
}
/**
* 源类Adaptee没有方法operation2
* 因此由适配器类需要补充此方法
*/
@Override
public void operation2() {
System.out.println("这是接口中的方法。");
}
}
public class Test {
public static void main(String[] args) {
Target adapter = new Adapter(new Adaptee());
adapter.operation1();
adapter.operation2();
}
}
运行结果如下:
接口适配(Default Adapter)模式为一个接口提供缺省实现,这样子类型可以从这个缺省实现进行扩展,而不必从原有接口进行扩展。
/**
* @author Evan Walker 昂焱数据: https://www.ayshuju.com
* @version 1.0
* @desc
* @date 2023/06/08 16:27:14
*/
/**
* 目标接口
*/
interface Target{
void operation1();
void operation2();
void operation3();
}
/**
* 定义一个抽象类,来选择需要重写的类
*/
abstract class abstractAdaptee implements Target{
@Override
public void operation1(){
System.out.println("默认实现operation1");
}
@Override
public abstract void operation2();//这个方法必须由子类来重写
@Override
public void operation3(){
System.out.println("默认实现operation3");
}
}
/**
* 定义一个类来继承abstractAdaptee类
* 通过接口和抽象类的结合,我们在子类中可以选择性的去实现那些抽象方法
*/
class Adapter extends abstractAdaptee{
@Override
public void operation2() {
System.out.println("子类必须重写这个方法");
}
}
public class Test {
public static void main(String[] args) {
Target adapter = new Adapter();
adapter.operation1();
adapter.operation2();
adapter.operation3();
}
}
运行结果如下:
更多消息资讯,请访问昂焱数据(https://www.ayshuju.com)