1.定义
适配器模式,即定义一个包装类,用于包装不兼容接口的对象
包装类 = 适配器Adapter;
被包装对象 = 适配者Adaptee = 被适配的类
2.主要的作用
把一个类的接口变换成客户端所期待的另一种接口,从而使原本接口不匹配而无法一起工作的两个类能够在一起工作。
适配器模式的形式分为:类的适配器模式和对象的适配器模式
3. 解决的问题
原本由于接口不兼容而不能一起工作的那些类可以在一起工作。
4. 原理
4.1.类图
- 解决方案:为使Target能够使用Adaptee类里的SpecificRequest方法,故提供一个中间环节Adapter类(继承Adaptee & 实现Target接口),把Adaptee的API与Target的API衔接起来(适配)。
4.2步骤
步骤1: 创建Target接口;
public interface Target {
//这是源类Adapteee没有的方法
public void Request();
}
步骤2: 创建源类(Adaptee) ;
public class Adaptee {
public void SpecificRequest(){
}
}
步骤3: 创建适配器类(Adapter)
//适配器Adapter继承自Adaptee,同时又实现了目标(Target)接口。
public class Adapter extends Adaptee implements Target {
//目标接口要求调用Request()这个方法名,但源类Adaptee没有方法Request()
//因此适配器补充上这个方法名
//但实际上Request()只是调用源类Adaptee的SpecificRequest()方法的内容
//所以适配器只是将SpecificRequest()方法作了一层封装,封装成Target可以调用的Request()而已
@Override
public void Request() {
this.SpecificRequest();
}
}
步骤4:定义具体使用目标类,并通过Adapter类调用所需要的方法从而实现目标
public class AdapterPattern {
public static void main(String[] args){
Target mAdapter = new Adapter();
mAdapter.Request();
}
}
5.案例
- 进口电视机要求电压(110V)与国内插头标准输出电压(220V)不兼容
- 解决方案:设置一个适配器将插头输出的220V转变成110V
5.1使用步骤
步骤1: 创建Target接口(期待得到的插头):能输出110V(将220V转换成110V)
public interface Target {
//将220V转换输出110V(原有插头(Adaptee)没有的)
public void Convert_110v();
}
步骤2: 创建源类(原有的插头) ;
class PowerPort220V{
//原有插头只能输出220V
public void Output_220v(){
}
}
步骤3:创建适配器类(Adapter)
class Adapter220V extends PowerPort220V implements Target{
//期待的插头要求调用Convert_110v(),但原有插头没有
//因此适配器补充上这个方法名
//但实际上Convert_110v()只是调用原有插头的Output_220v()方法的内容
//所以适配器只是将Output_220v()作了一层封装,封装成Target可以调用的Convert_110v()而已
@Override
public void Convert_110v(){
this.Output_220v;
}
}
步骤4:定义具体使用目标类,并通过Adapter类调用所需要的方法从而实现目标(不需要通过原有插头)
//进口机器类
class ImportedMachine {
@Override
public void Work() {
System.out.println("进口机器正常运行");
}
}
//通过Adapter类从而调用所需要的方法
public class AdapterPattern {
public static void main(String[] args){
Target mAdapter220V = new Adapter220V();
ImportedMachine mImportedMachine = new ImportedMachine();
//用户拿着进口机器插上适配器(调用Convert_110v()方法)
//再将适配器插上原有插头(Convert_110v()方法内部调用Output_220v()方法输出220V)
//适配器只是个外壳,对外提供110V,但本质还是220V进行供电
mAdapter220V.Convert_110v();
mImportedMachine.Work();
}
}
6.实验题:
- 实现一个双向适配器实例,使得猫(Cat)可以学狗(Dog)叫,狗可以学猫抓老鼠。绘制相应类图并使用代码编程模拟。
interface Cat {
public void play();
}
class concrectCat implements Cat{
public void play(){
System.out.println("猫捉老鼠");
}
}
interface Dog {
public void cry();
}
class concrectDog implements Dog{
public void cry(){
System.out.println("狗叫");
}
}
class twowayAdapter implements Cat, Dog {
private Cat cat;
private Dog dog;
public twowayAdapter(Cat cat) {
this.cat = cat;
}
public twowayAdapter(Dog dog) {
this.dog = dog;
}
public void cry() {
cat.play();
}
public void play() {
dog.cry();
}
}
public class Test {
// 客户端代码
public static void main(String[] args) {
System.out.println("狗学");
Cat cat = new concrectCat();
Dog dog = new twowayAdapter(cat);
dog.cry();
System.out.println("猫学");
Dog dog1 = new concrectDog();
Cat cat1 = new twowayAdapter(dog1);
cat1.play();
}
}