适配器模式是结构型模式中的一种,他经常用于将两个没有联系的接口进行适配,使之可以结合使用。其中联合不相关接口的对象就是成为适配器。

就拿现实生活中的手机充电器举例子,我们就可以把手机充电器当做适配器,因为一般的插座电源都是220V的,但是手机电池是3V的,手机充电器就在手机电源和一般插座之间充当适配器的作用。

现在我们就拿这个例子来使用java实现适配器模式。

首先,我们实现两个类,Volt 和 Socket 类

Volt.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
package com.walterlife.dp.AdapterDP;

import org.apache.log4j.Level;
import org.apache.log4j.Logger;

public class Volt {
private int volts;
static Logger logger = Logger.getLogger(Volt.class);

public Volt(int v) {
this.volts = v;
}

public void setVolts(int v) {
this.volts = v;
}

public int getVolts() {
return this.volts;
}
}

Socket.java

1
2
3
4
5
6
7
package com.walterlife.dp.AdapterDP;

public class Socket {
public Volt getVolt() {
return new Volt(220);
}
}

现在我们开始实现产生3种 volts(3V, 12V, 220V)的电源适配器。所以首先创建一个适配器接口类来定义获得vlot的方法

SocketAdapter.java

1
2
3
4
5
6
7
8
9
package com.walterlife.dp.AdapterDP;

public interface SocketAdapter {
public Volt get220Volt();

public Volt get12Volt();

public Volt get3Volt();
}

两种适配器模式实现方法

  1. Class Adapter 通过Java extends 来继承 源对象, 比如 Socket

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    package com.walterlife.dp.AdapterDP;

    public class SocketClassAdapterImpl extends Socket implements SocketAdapter {

    public Volt get220Volt() {
    return getVolt();
    }

    public Volt get12Volt() {
    return convertVolt(getVolt(), 10);
    }

    public Volt get3Volt() {
    return convertVolt(getVolt(), 40);
    }

    private Volt convertVolt(Volt v, int multi) {
    if(v == null) {
    logger.error("param Volt v is not valid !!!");
    return null;
    }
    return new Volt(v.getVolts() / multi);
    }
    }
  2. Object Adapter 通过Java 组合,使Adapter 包含源对象

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    package com.walterlife.dp.AdapterDP;

    import org.apache.log4j.Logger;

    public class SocketClassAdapterImpl implements SocketAdapter {
    static Logger logger = Logger.getLogger(SocketClassAdapterImpl.class);

    private Socket socket = new Socket();

    public Volt get220Volt() {
    return socket.getVolt();
    }

    public Volt get12Volt() {
    return convertVolt(socket.getVolt(), 18);
    }

    public Volt get3Volt() {
    return convertVolt(socket.getVolt(), 40);
    }

    private Volt convertVolt(Volt v, int multi) {
    if(v == null) {
    logger.error("param Volt v is not valid !!!");
    return null;
    }
    return new Volt(v.getVolts() / multi);
    }
    }

两种方式最终的结果都是一致的。

当然,Adapter Interface 也可以是一个 Abstract Class

下面是Adapter Pattern 的测试代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
public static Volt getVolt(SocketAdapter adapter, int v) {
Volt volt = null;
if(v <= 0) {
logger.error("param v: " + v + " is not valid !!!");
} else if(adapter == null) {
logger.error("param adapter is not null !!!");
} else {
switch(v) {
case 3:
volt = adapter.get3Volt();
break;
case 10:
volt = adapter.get12Volt();
break;
case 220:
volt = adapter.get220Volt();
break;
default:
volt = adapter.get220Volt();
break;
}
}
return volt;
}

public static void testAdapter() {
SocketClassAdapterImpl socketAdapter = new SocketClassAdapterImpl();
Volt v3 = getVolt(socketAdapter, 3);
Volt v12 = getVolt(socketAdapter, 12);
Volt v220 = getVolt(socketAdapter, 220);
if(v3 != null && v12 != null && v220 != null) {
System.out.printf("v3 volts: %d\nv12 volts: %d\nv220 volts: %d\n", v3.getVolts(), v12.getVolts(), v220.getVolts());
} else {
System.out.printf("v3 null: %s\nv12 null: %s\nv220 null: %s\n",
((v3 != null) ? "no" : "yes"),
((v12 != null) ? "no" : "yes"),
((v220 != null) ? "no" : "yes"));
}
}

测试结果

1
2
3
v3 volts: 3
v12 volts: 12
v220 volts: 220

留言