什么是适配器模式
适配器模式暂且不聊,先聊一下生活中常见的适配器有哪些:
网线转接头:
现在的笔记本越做越薄,厂家甚至直接取消了传统的网线接口,导致网线不能直接插在电脑上,至于需要插网线的时候,我们就需要另购网线转接头,网线插在转接头上之后,另一端通过usb或者雷电接口连接电脑。
变压器:
已知家庭用电都是220v的,但是国家电网向各个城市的变电站输送的可不止220v,各个变电站第一次变压后向各个城区或者小区输送用电的也是大于220v的电压,经过各地区或者小区的变压器最后变压后才到了家庭用电的标准220v。
以上的转接头和变压器就是典型的适配器行为,把原本不能直接使用的事物通过某种适配器的代理,变成可以供使用者直接使用的事物,提供给使用者消费。
在编程中适配器模式就是这种思想的体现:有一个方法,可能由于参数列表字段的原因,不能被调用者直接使用,通过一个中间层,也就是适配器,来包装这个方法,并且提供匹配调用者要求的方法供调用者使用,这样就达到了适配的目的。
类适配器
最简单的适配器模式思想实现:类适配器
以网线转接头场景为例
网线:提供上网能力,所以网线就是被适配对象
package com.leolee.createObjectPattern.decorator.surfInternetDemo.demo1;
/**
* @ClassName CableInternet
* @Description: 网线
* @Author LeoLee
* @Date 2020/11/18
* @Version V1.0
**/
public class CableInternet {
public void connectToInternet() {
System.out.println("成功连接网络");
}
}
适配器抽象类:将网线的上网能力进行一个抽象
package com.leolee.createObjectPattern.decorator.surfInternetDemo.demo1;
//适配器
public interface Adapter {
public void usbToCableInternet();
}
具体的适配器:也就是真正实现适配能力的类,实现适配器抽象类,因为需要通过该适配器使用网线的上网能力,所以继承网线类,获得父类的上网能力
package com.leolee.createObjectPattern.decorator.surfInternetDemo.demo1;
/**
* @ClassName CableInternetAdapter
* @Description: TODO
* @Author LeoLee
* @Date 2020/11/18
* @Version V1.0
**/
public class CableInternetAdapter extends CableInternet implements Adapter {
@Override
public void usbToCableInternet() {
super.connectToInternet();
}
}
电脑:需要获取上网能力,适配器的使用者。由于可能会有很多品牌或者很多种类型的适配器都能满足网线转接头的代理需求,所以这里请求上网方法使用的是适配器抽象类,方便接收不同的适配器
package com.leolee.createObjectPattern.decorator.surfInternetDemo.demo1;
/**
* @ClassName Computer
* @Description: TODO
* @Author LeoLee
* @Date 2020/11/18
* @Version V1.0
**/
public class Computer {
//请求上网
public void net(Adapter adapter) {
adapter.usbToCableInternet();
}
}
测试
package com.leolee.createObjectPattern.decorator.surfInternetDemo.demo1;
/**
* @ClassName Test
* @Description: TODO
* @Author LeoLee
* @Date 2020/11/18
* @Version V1.0
**/
public class Test {
public static void main(String[] args) {
Computer computer = new Computer();
computer.net(new CableInternetAdapter());
}
}
对象适配器
类适配器有个明显的缺点,适配器继承了网线才获取的上网能力,这样就不方便之后的拓展,耦合性太高,设计模式种能不使用继承就不要使用继承。不符合里氏替换原则,所以对象适配器使用的是组合形式来获取网线的上网能力
改造类适配器代码如下:
具体的适配器不再继承网线类,而是将网线类作为一个变量,通过构造方法的形式对该变量进行赋值
package com.leolee.createObjectPattern.decorator.surfInternetDemo.demo2;
/**
* @ClassName CableInternetAdapter
* @Description: TODO
* @Author LeoLee
* @Date 2020/11/18
* @Version V1.0
**/
public class CableInternetAdapter implements Adapter {
private CableInternet cableInternet;
public CableInternetAdapter(CableInternet cableInternet) {
this.cableInternet = cableInternet;
}
@Override
public void usbToCableInternet() {
cableInternet.connectToInternet();
}
}
测试
package com.leolee.createObjectPattern.decorator.surfInternetDemo.demo2;
/**
* @ClassName Test
* @Description: TODO
* @Author LeoLee
* @Date 2020/11/18
* @Version V1.0
**/
public class Test {
public static void main(String[] args) {
Computer computer = new Computer();
computer.net(new CableInternetAdapter(new CableInternet()));
}
}