适配器,在生活中也经常用到,我们买了欧洲的电子产品,如果回国用,那么原厂的插头是没有办法引用到国内的插座上的,那么我们最省事的方式就是买个转接头,而不是重新买个产品或者电源线,因为这样才是最省的方案。适配器模式就是这样的原理。
假设我们有一只火鸡,我们要将其伪装成鸭子该怎么处理呢?我们需要一个适配器,让他拥有所有鸭子的特征就好了
下面我们创建了鸭子的接口以及火鸡的接口
1 | public interface Duck { |
并且我们有了一个wildTurkey的类1
2
3
4
5
6
7
8public class WildTurkey implements Turkey {
public void gobble() {
System.out.println("Gobble gobble!");
}
public void fly() {
System.out.println("Flying a short distance");
}
}
那么我们需要用火鸡来伪装一下鸭子,我们该怎么办呢?
我们需要实现一个适配器,这个适配器要实现鸭子的所有的接口,这些接口的具体实现实际上是转接调用的火鸡的接口,或者需要重新实现。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16public class TurkeyAdapter implements Duck {
Turkey turkey;
public TurkeyAdapter(Turkey turkey) {
this.turkey = turkey;
}
public void quack() {
turkey.gobble();
}
public void fly() {
for (int i = 0; i < 5; i++) {
turkey.fly();
}
}
}
当我们运行测试用例的时候,通过将火鸡进行适配后,就可以表现出鸭子的功能了。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20public class adapterTest {
public static void main(String[] args) {
MallardDuck mallardDuck = new MallardDuck();
WildTurkey wildTurkey = new WildTurkey();
Duck turkeyAdaptor = new TurkeyAdapter(wildTurkey);
System.out.println("Turkey says:");
wildTurkey.gobble();
wildTurkey.fly();
System.out.println("MallardDuck says:");
mallardDuck.quack();
mallardDuck.fly();
System.out.println("A new Duck says:");
turkeyAdaptor.quack();
turkeyAdaptor.fly();
}
}
测试结果如下:
1 | Turkey says: |
使用适配器的过程
- 客户通过目标接口调用适配器的方法对适配器发出请求
- 适配器使用被适配器接口把请求转换成被适配者的一个后者多个调用接口
- 客户接收到调用的结果,但并未察觉到这一切是适配器在起转换作用。
适配器模式将一个类的接口,转换成客户期望的另一个接口,适配器让原本接口不兼容的类可以合作无间
类适配器
上面的例子是对象适配器,他实际上是用的组合的方式在解决问题,而类适配器使用的是继承的方式,而且是多重继承,如下所示:
对象适配器和类适配器的区别
上面的图已经很明确的显示了对象适配器和类适配器的区别
对象适配器使用组合,它不仅可以适配类,也可以适配该类的任何子类。而类适配器做不到这一点,它使用继承,它不需要重新实现它的适配者。
代码链接如下
https://github.com/changyuanchn/DesignPattern/tree/main/src/com/changyuan/adapterPattern