- 角色
- 适配器模式分类
- 类适配器模式
- 对象适配器模式
- 默认(接口)适配器模式
- 总结
1. 角色
例子:去英国旅游,但是英国的电压是230V,国内是220V
- Target(目标):目标可以是具体的或抽象的类,也可以是接口。这里230V是我们的目标
- Adaptee(已有接口):一般是接口。这里220V是我们已有的接口
- Adapter(适配器):这里指的是转换插头(220V转230)。我们需要实现这个类
2 适配器模式分类
适配器模式有分三类:
类适配器模式(class adapter pattern):Target是接口,Adaptee是类,Adapter继承Adaptee实现Target,重写Target的方法,在里面调用并修改super的方法
对象适配器模式(object adapter pattern):Target是接口,Adaptee是类,Adapter实现Target聚合Adaptee,重写Target的方法,在里面调用并修改属性adaptee的方法
缺省适配器模式(default adapter pattern),也叫默认适配器模式、接口适配器模式
2.1 类适配器模式
(1)类图
(2)代码
- Target
public interface PowerTarget {
public int output5V();
}
- Adaptee
public class PowerAdaptee {
private int output = 220;
public int output220V() {
System.out.println("电源输出电压:" + output);
return output;
}
}
- Adapter
public class PowerAdapter extends PowerAdaptee implements PowerTarget{
@Override
public int output5V() {
return super.output220V()/44;
}
}
- 客户端调用
public class ClassAdapterPatternTest {
public static void main(String[] args) {
PowerTarget target = new PowerAdapter();
target.output5V();
}
}
2.2 对象适配器模式
(1)类图
(2)代码(Target,Adaptee,客户端调用代码同上)
- Adapter
public class PowerAdapter implements PowerTarget{
private PowerAdaptee powerAdaptee; //聚合Adaptee
public PowerAdapter(PowerAdaptee powerAdaptee) {
super();
this.powerAdaptee = powerAdaptee;
}
@Override
public int output5V() {
return powerAdaptee.output220V()/44;
}
}
2.3 缺省(默认/接口)适配器模式
(1)类图
(2)代码
- Target
public interface SampleOperation {
public abstract void operation1();
public abstract void operation2();
public abstract void operation3();
public abstract void operation4();
public abstract void operation5();
}
- Adapter
public abstract class DefaultAdapter implements SampleOperation{
@Override
public void operation1() {}
@Override
public void operation2() {}
@Override
public void operation3() {}
@Override
public void operation4() {}
@Override
public void operation5() {}
}
- 客户端调用
- 测试缺省适配器模式需要用到的类(Operator.java)
public class Operator {
private SampleOperation sampleOperation;
public void addOperation(SampleOperation sampleOperation) {
this.sampleOperation = sampleOperation;
}
public void operation1() {sampleOperation.operation1();}
public void operation2() {sampleOperation.operation2();}
public void operation3() {sampleOperation.operation3();}
public void operation4() {sampleOperation.operation4();}
public void operation5() {sampleOperation.operation5();}
}
- 客户端测试
public class DefaultAdapterTest {
public static void main(String[] args) {
// 1、原来要实现所有操作类的操作
Operator operator1 = new Operator();
operator1.addOperation(new SampleOperation() {
@Override
public void operation1() {}
@Override
public void operation2() {
System.out.println("操作2");
}
@Override
public void operation3() {}
@Override
public void operation4() {}
@Override
public void operation5() {}
});
operator1.operation2();
// 2、使用缺省适配器只需要实现需要用到的接口方法
Operator operator2 = new Operator();
operator2.addOperation(new DefaultAdapter() {
@Override
public void operation2() {
System.out.println("操作2");
}
});
operator2.operation2();
}
}
3. 总结
- 类适配 vs 对象适配
- 类适配:
- 继承,使得代码结构看上去更灵活
- 但是由于不能多继承,适配者类只能有一个
- 对象适配:
- 一个对象适配器可以把多个不同的适配者adaptee适配到一个目标
- 修改代码麻烦
- 缺省适配
- 最为推荐:可复用,可扩展,可解耦
- 但是过多地使用适配器,增加系统理解难度
其他
spring AOP,spring JPA,spring MVC中对适配器模式的使用:https://blog.csdn.net/wwwdc1012/article/details/82780560