我的理解:适配器就类似于转接口,负责把,A类型通过转接头T转化成为B类型,
由 A–>T–>B的过程我们称之为适配的过程。
生活中比较常见的例子就是变压器,我们手机充电器,手机充电器会把220v的高压转换成为5v的手机充电器,这个就是我们所需要的电压。
怎么实现这个过程呢:
只要是220v电压都是这个接口
220v电压接口
package com.适配器模式.bianyaqi;
public interface V220Interface {
void v220ChongDian();
}
220的实现类
package com.适配器模式.bianyaqi;
public class V220Imp implements V220Interface{
@Override
public void v220ChongDian() {
System.out.println("220v电压");
}
}
5v电压接口
package com.适配器模式.bianyaqi;
public interface V5Interface {
String v5ChongDian();
}
需求就是将 220v的电压转换成为5v的电压,我们应该怎么实现呢
1,定义一个变压器,有人就像,我之间定义一个变压器类然后实现v5Interface接口我就不久可以,由5v的电压,就可以充电了
2.怎么让220v电压让变压器类知道呢有两个法子
(1)通过对象的关联来处理,我直接在编译器里创建一个220v的电压,然后把它转换成为5v的
package com.适配器模式.bianyaqi;
public class BianYaQi implements V5Interface{
private V220Interface v220Interface = new V220Imp();
@Override
public String v5ChongDian() {
this.v220Interface.v220ChongDian();
System.out.println("经过了一系列变压器的处理 变成了 5v" );
return "5v---> 类对象关联";
}
}
(2还可以通过继承220v的实现类的法子,来获得220v的电压,我继承了220v我就是220v然后在去实现5v的电压我就可以得到5v的电压了
package com.适配器模式.bianyaqi;
public class BianYaQi02 extends V220Imp implements V5Interface{
@Override
public String v5ChongDian() {
super.v220ChongDian();
System.out.println("经过了一系列变压器的处理 变成了 5v" );
return "5v --->类的继承处理的";
}
}
通过上面的实例我们就可以得到适配器的定义了:
将一个接口转换成客户希望的另一个接口,使接口不兼容的那些类可以一起工作,其别名为包装器(Wrapper)。适配器模式既可以作为类结构型模式(类的继承),也可以作为对象结构型模式(对象的关联)。
在适配器模式中,我们通过增加一个新的适配器类来解决接口不兼容的问题,使得原本没有任何关系的类可以协同工作。
根据适配器类与适配者类的关系不同,适配器模式可分为对象适配器和类适配器两种,在对象适配器模式中,适配器与适配者之间是关联关系;在类适配器模式中,适配器与适配者之间是继承(或实现)关系。
类图
角色
目标抽象类:Target,该角色把其他类转换为我们期望的接口,可以是一个抽象类或接口,也可以是具体类。
被适配者: Adaptee ,原有的接口,也是希望被适配的接口。
适配器: Adapter, 将被适配者和目标抽象类组合到一起的类。
被适配类:Adaptee // 相当于220v电压
public class Adaptee {
public void adapterRequest(){
System.out.println("被适配者的方法");
}
}
目标抽象:Target接口//相当于5v电压的接口
public interface Target {
void request();
}
怎么才可以在目标接口中的 request() 调用 Adaptee 的 adapteeRequest() 方法呢?
如果直接实现 Target 是不行的,还是调用不到被适配类的方法
ConcreteTarget类,具体目标类,实现了Target接口。
public class ConcreteTarget implements Target {
@Override
public void request() {
System.out.println("concreteTarget目标方法");
}
}
类适配器
如果通过一个适配器类,实现 Target 接口,同时继承了 Adaptee 类,然后在实现的 request() 方法中调用父类的 adapteeRequest() 即可实现
Adapter类相当于变压器
public class Adapter extends Adaptee implements Target {
@Override
public void request() {
super.adapterRequest();
}
}
应用:
public class Test {
public static void main(String[] args) {
Target target = new ConcreteTarget();
target.request();
Target adapterTarget = new Adapter();
adapterTarget.request();
}
}
对象适配器
对象适配器与类适配器不同之处在于,类适配器通过继承来完成适配,对象适配器则是通过关联来完成,这里稍微修改一下 Adapter 类即可将转变为对象适配器,把被适配者Adaptee关联进入适配器类
Adapter // 相当于编译器2
public class Adapter implements Target {
private Adaptee adaptee = new Adaptee();
public void request() {
adaptee.adapterRequest();
}
}
应用
public class Test {
public static void main(String[] args) {
Target target = new ConcreteTarget();
target.request();
Target adapterTarget = new Adapter();
adapterTarget.request();
}
}
应用场景:
想要使用一个已经存在的类,但是它却不符合现有的接口规范,导致无法直接去访问,这时创建一个适配器就能间接去访问这个类中的方法。
我们有一个类,想将其设计为可重用的类,我们可以创建适配器,将这个类来适配其他没有提供合适接口的类。
和其他模式的对比
适配器模式和装饰者模式:装饰者模式是对以前的类进行进一步的封装与增强,目的是一层一层的增加功能,而适配器模式主要是为了协调多个调用者不同的调用方式而设计出来的。
适配器模式和外观模式:都是对现有类的封装,外观模式定义了新的接口,适配器则是复用已有的接口,适配器是两个接口协调工作,而外观模式则是为了别人使用的方便,提供了一个比较易用的接口。