设计模式之适配器模式
复用已有代码来完成现有功能
- 概念
- 使用场景
- 类图
- 代码实例
概念
适配器: 我们国家使用的电脑和手机充电必须在220V电压进行的,但是有些国家例如泰国的电压就达不到220V这个时候我们就需要使用电源适配器进行将低电压转换成高电压。 适配器就是使用一个东西适合另一个东西的东西。
使用场景
例如原来系统某类一些功能和现有逻辑类似,因此我们想要复用代码,但是又要满足现有接口。 一个类需要实现现有接口并且内部实现逻辑是使用适配类中的实现的类称为适配类。
需求场景:
两孔插座和三孔插口的电器,现在我想通过两孔插座进行给电器充电,这个时候该怎么办?
分析:
就如概念所述,我想要使用现有的东西,但是这个东西并不适合,因此就需要考虑用适配器了。通过一个两孔插座适配器,上面有三孔插座,同时也有两孔插口。这个时候就可以使用两孔插座上给电器充电了。
下面就是通过两种方式进行实现上面的需求,一种是通过继承适配类和一种关联适配类对象方式,推荐使用后面一种,因为java只能有一个父类,不支持多继承。使用关联方式灵活性更好。
类图
SocketObjectAdapter:两孔插座适配类 Adapter
TwoHoleSocket:两孔插座 适配的类 Adaptee
ThreeHoleSocket:客户端使用的接口,三孔电器 Target
代码实例
TwoHoleSocket 两孔插座接口
/**
* @author duanyimiao
* @create 2018-07-27 10:10 AM
* @description 两孔插座
**/
public interface TwoHoleSocket {
public void executeTwoPlug();
}
TwoHoleSocketImpl 两孔插座实现
/**
* @author duanyimiao
* @create 2018-07-27 10:20 AM
* @description 两空插座实现
**/
public class TwoHoleSocketImpl implements TwoHoleSocket {
@Override
public void executeTwoPlug() {
System.out.println("execute two plug operate");
}
}
ThreeHoleSocket 三孔插座接口
/**
* @author duanyimiao
* @create 2018-07-27 10:21 AM
* @description 三孔的插座
**/
public interface ThreeHoleSocket {
public void executeThreeHole();
}
SocketObjectAdapter 对象方式的适配类
/**
* @author duanyimiao
* @create 2018-07-27 10:25 AM
* @description 如果三接口电器想使用两接口的插作,那么就应该使用一个适配器进行转换
* 适配器分为 类适配(继承) 对象适配(聚合) 接口适配
*
* SocketObjectAdapter 为两孔插座适配器(对象适配)
**/
public class SocketObjectAdapter implements ThreeHoleSocket{
private TwoHoleSocket twoHoleSocket;
public SocketObjectAdapter(){
}
public SocketObjectAdapter(TwoHoleSocket twoHoleSocket){
this.twoHoleSocket = twoHoleSocket;
}
@Override
public void executeThreeHole() {
System.out.println("by object adapter execute exchange to two socket hole ");
twoHoleSocket.executeTwoPlug();
}
}
SocketClassAdapter 使用继承适配类实现的(不推荐使用继承方式实现)
/**
* @author duanyimiao
* @create 2018-07-27 10:25 AM
* @description 如果三接口电器想使用两接口的插作,那么就应该使用一个适配器进行转换
* 适配器分为 类适配(继承) 对象适配(聚合) 接口适配
*
* SocketClassAdapter 为类适配器
**/
public class SocketClassAdapter extends TwoHoleSocketImpl implements ThreeHoleSocket{
@Override
public void executeThreeHole() {
System.out.println("by class adapter execute exchange to two socket hole ");
executeTwoPlug();
}
}
MainTest 测试类
/**
* @author duanyimiao
* @create 2018-07-27 10:38 AM
* @description
**/
public class MainTest {
public static void main(String[] args) {
//类适配器
SocketClassAdapter socketClassAdapter = new SocketClassAdapter();
ThreeHoleSocket threeHoleSocket = socketClassAdapter;
threeHoleSocket.executeThreeHole();
//对象适配器
TwoHoleSocket twoHoleSocket = new TwoHoleSocketImpl();
SocketObjectAdapter socketObjectAdapter = new SocketObjectAdapter(twoHoleSocket);
ThreeHoleSocket threeHoleSocket1 = socketObjectAdapter;
threeHoleSocket1.executeThreeHole();
}
}
输出结果
by class adapter execute exchange to two socket hole
execute two plug operate
by object adapter execute exchange to two socket hole
execute two plug operate
以下为接口方式的适配器,有时候我们是需要实现接口中的几个方法,没有必要都需要实现,可以采用接口适配进行完成。
SocketHole 插孔接口
/**
* @author duanyimiao
* @create 2018-07-27 10:21 AM
* @description 插孔接口
**/
public interface SocketHole {
public void execute1();
public void execute2();
public void execute3();
}
SocketInterfaceAdapter 接口适配
其他类想要实现execute1方法只需要继承SocketInterfaceAdapter然后实现execute1方法不需要再实现execute2 execute3方法
/**
* @author duanyimiao
* @create 2018-07-27 10:25 AM
* @description 适配器分为 类适配(继承) 对象适配(聚合) 接口适配
* SocketInterfaceAdapter就是接口适配器,其他类直接继承该类,就可以实现自己需要的方法,其他方法可以不用实现,代码会更简洁
**/
public abstract class SocketInterfaceAdapter implements SocketHole {
@Override
public void execute1(){
}
@Override
public void execute2(){
}
@Override
public void execute3(){
}
}