适配器模式(Adapter Pattern)
适配器模式(Adapter Pattern)是作为两个不兼容的接口之间的桥梁,属于结构型模式。
这种模式涉及到一个单一的类,该类负责统一本不兼容的接口功能。
使用
介绍
角色:
- 目标(Target)接口:当前系统业务所期待的接口,它可以是抽象类或接口。将要使用的接口,内部包含适配者相关的逻辑。
- 适配者(Adaptee)类:它是被访问和适配的现存组件库中的组件接口。简单来说就是旧接口、被适配接口。
- 适配器(Adapter)类:它是一个转换器,通过继承或引用适配者的对象,把适配者接口转换成目标接口,让客户按目标接口的格式访问适配者。
意图:
- 将两个类的接口,通过适配器转化为具有一定规则的统一接口。
主要解决:
- 新系统对旧系统的接口兼容
- 两接口的统一输出
何时使用:
- 新系统对旧系统不兼容的接口的使用需要。
- 想要将某些不太相关的接口通过一个类来统一使用。
- 通过接口转换,将一个类插入另一个类系中。
- (比如老虎和飞禽,现在多了一个飞虎,在不增加实体的需求下,增加一个适配器,在里面包容一个虎对象,实现飞的接口。)
如何解决:
- 继承或依赖(推荐)。
关键代码:
- 适配器继承或依赖已有的对象,实现想要的目标接口。
优缺点
优点:
- 可以让任何两个没有关联的类一起运行。
- 不通过改变原有代码而重新使用及代码。
- 提高了类的复用。
- 增加了类的透明度。
- 灵活性好。
缺点:
- 降低可读性
- 过多地使用适配器,会让系统非常零乱,不易整体进行把握。比如,明明看到调用的是 A 接口,其实内部被适配成了 B 接口的实现,一个系统如果太多出现这种情况,无异于一场灾难。**因此如果不是很有必要,可以不使用适配器,而是直接对系统进行重构。 **
- 由于 JAVA 至多继承一个类,所以至多只能适配一个适配者类,而且目标类必须是抽象类。
使用场景:
适用场景分析:
- 修改一个正常运行的系统的接口。在不破坏原有系统的情况下进行修改。
注意事项:
- 用来解决遗留问题,而非尽可能多的使用该模式。
结构与实现
适配器模式分为类适配器模式和对象适配器模式两种,前者类之间的耦合度比后者高,且要求程序员了解现有组件库中的相关组件的内部结构,所以应用相对较少些。
类适配器模式
UML
代码
//适配器
public class ClassAdapter extends Adaptee implements Target{
@Override
public String use() {
String msg = getMsg();
return msg+"+一段新代码~逻辑被修改了!";
}
//客户端
public static void main(String[] args) {
ClassAdapter adapter = new ClassAdapter();
System.out.println(adapter.use());
}
}
//目标类
interface Target{
String use();
}
//适配者,被适配的类
class Adaptee{
public String getMsg(){
return "一段老代码被调用!";
}
}
对象适配器模式
UML
代码
public class ObjectAdapter implements Target {
private Adaptee adaptee;
//构造器传入一个私有适配者对象
public ObjectAdapter(Adaptee adaptee) {
this.adaptee = adaptee;
}
@Override
public String use() {
//调用该对象
return adaptee.getMsg() + "代码逻辑变动!";
}
public static void main(String[] args) {
Adaptee adaptee = new Adaptee();
ObjectAdapter adapter = new ObjectAdapter(adaptee);
System.out.println(adapter.use());
}
}
//目标类
interface Target{
String use();
}
//适配者,被适配的类
class Adaptee{
public String getMsg(){
return "一段老代码被调用!";
}
}
接口适配器模式
- 特殊的适配器模式,重点在于当一个类无需实现一个接口的全部方法。
- 通过接口适配器将所有方法默认实现空或者抛出异常的方式减轻接口的实现类方法必须实现的问题。
代码
public class InterfaceAdapter implements AdapteeInterface{
@Override
public void method1() {
}
@Override
public void method2() {
}
@Override
public void method3() {
}
@Override
public void method4() {
}
public static void main(String[] args) {
InterfaceAdapter adapter = new InterfaceAdapter(){
//覆盖适配器中的空接口
@Override
public void method1() {
super.method1();
System.out.println("新建并使用了被适配的接口");
}
};
adapter.method1();
}
}
interface AdapteeInterface {
void method1();
void method2();
void method3();
void method4();
}
interface AdapteeInterface {
void method1();
void method2();
void method3();
void method4();
}