一、概述
适配器模式 (Adapter Pattern) 是一种结构型设计模式,它通过将一个类的接口转换成客户端所期望的另一个接口,使得原本由于接口不兼容而无法一起工作的类能够协同工作。适配器模式分为类适配器模式和对象适配器模式,前者类之间的耦合度比后者高,且要求程序员了解现有组件库中的相关组件的内部结构,故应用相对较少。
二、结构
适配器模式 (Adapter) 包含以下主要角色:
- 目标 (Target) 接口:当前系统业务所期待的接口,它可以是抽象类或接口。
- 被适配 (Adaptee) 类:它是被访问和适配的现存组件库中的组件接口。
- 适配器 (Adapter) 类:它是一个转换器,通过继承或引用适配者的对象,把适配者接口转换成目标接口,让客户按目标接口的格式访问适配者。
适配器模式包括三类:类适配器模式、对象适配器模式、接口适配器模式
以一个日常生活中的简单例子来说明:
假如我们家里有一个电器需要一个两孔的插座,但是家里只有一个三孔插座,这个时候我们就需要一个适配器,把两孔的插头插到三孔的插座上面。
四、类适配器模式实例
1、Target接口
package com.xu.demo.adapterPattern;
/**
* 三孔插座
* 希望有个三孔插头
*/
public interface Target {
void tripleCharge();
}
2、Adaptee类
package com.xu.demo.adapterPattern;
/**
* 适配者接口
* 当前只有两孔插头
*/
public class Adaptee {
//实际调用的是二孔插头
public void doubleCharge(){
System.out.println("插头插入了两孔插座");
}
}
3、ClassAdapter类
package com.xu.demo.adapterPattern;
/**
* 适配器类
*/
class ClassAdapter extends Adaptee implements Target{
//将三孔插座转换为两孔
@Override
public void tripleCharge() {
super.doubleCharge();
}
}
4、AdapterPattern类
package com.xu.demo.adapterPattern;
public class AdapterPattern {
public static void main(String[] args) {
Target target=new ClassAdapter();
target.tripleCharge(); //用户使用了三孔的插座,但是插入的是两孔
}
}
运行结果:
五、对象适配器模式实例
对象适配模式中的适配器类不再继承适配者的类,而是通过组合的方式在适配器类中获取适配者对象,从而实现将适配者转换为目标类。对比来说,比类适配器更加灵活。
1、ClassAdapter2类
package com.xu.demo.adapterPattern;
public class ClassAdapter2 implements Target {
private Adaptee adaptee;
public ClassAdapter2(Adaptee adaptee) {
this.adaptee = adaptee;
}
@Override
public void tripleCharge() {
adaptee.doubleCharge(); //将三孔插座转换为两孔
}
}
2、ObjectAdapter类
package com.xu.demo.adapterPattern;
public class ObjectAdapter {
public static void main(String[] args) {
Target target=new ClassAdapter2(new Adaptee());
target.tripleCharge(); //用户使用了三孔的插座,但是插入的是两孔
}
}
运行结果:
六、接口适配器模式
接口适配器模式借助中间抽象类空实现目标接口中的所有方法,子类选择性重写,可以减少不必要的方法。从表面上看,就好像是不再是客户端使用适配器,而是适配者自己去使用适配器为客户端提供我们需要的用途。
1、ClassAdapter类
package com.xu.demo.adapterPattern;
/**
* 适配器类
*/
class ClassAdapter implements Target{
//将三孔插座转换为两孔
@Override
public void tripleCharge() {
}
}
2、Adaptee类
package com.xu.demo.adapterPattern;
/**
* 适配者接口
* 当前只有两孔插头
*/
public class Adaptee extends ClassAdapter {
//实际调用的是二孔插头
@Override
public void tripleCharge() {
System.out.println("插头插入了两孔插座");
}
}
3、 InterfaceAdapter类
package com.xu.demo.adapterPattern;
public class InterfaceAdapter {
public static void main(String[] args) {
Adaptee adaptee=new Adaptee();
adaptee.tripleCharge(); //用户使用了三孔的插座,但是插入的是两孔
}
}
运行结果: