Java适配器设计模式详解:原理、实现与应用案例

适配器设计模式是结构设计模式中的一种,用于使两个不相关的接口能够协同工作。将这些不相关的接口连接起来的对象被称为适配器。

适配器模式

适配器设计模式的一个很好的现实示例是手机充电器。移动电池需要3伏特来充电,但常规插座提供的是120V(美国)或240V(印度)。因此,手机充电器充当移动充电插座和墙插之间的适配器。在本教程中,我们将尝试使用适配器设计模式实现多适配器。因此,首先我们将有两个类-伏特(Volt,用于测量伏特)和插座(Socket,产生恒定的120V伏特)。

package com.Olivia.design.adapter;

// 伏特类,用于测量电压
public class Volt {

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

	public int getVolts() {
		return volts;
	}

	public void setVolts(int volts) {
		this.volts = volts;
	}
	
}
package com.Olivia.design.adapter;

// 插座类,产生恒定的120V电压
public class Socket {

	public Volt getVolt(){
		return new Volt(120);
	}
}

现在我们想要构建一个适配器,可以产生3伏特、12伏特和默认的120伏特。所以首先我们将创建一个带有这些方法的适配器接口。

package com.Olivia.design.adapter;

// 插座适配器接口
public interface SocketAdapter {

	public Volt get120Volt();
		
	public Volt get12Volt();
	
	public Volt get3Volt();
}

双向适配器模式

在实施适配器模式时,有两种方法 – 类适配器和对象适配器 – 然而,这两种方法都会产生相同的结果。

  1. 类适配器- 这种形式使用Java继承并扩展源接口,对于我们来说是Socket类。
  2. 对象适配器- 这种形式使用Java组合,适配器包含源对象。

适配器设计模式 – 类适配器

这是我们适配器的类适配器方法实现。

package com.Olivia.design.adapter;

// 使用继承实现适配器模式
public class SocketClassAdapterImpl extends Socket implements SocketAdapter{

	@Override
	public Volt get120Volt() {
		return getVolt();
	}

	@Override
	public Volt get12Volt() {
		Volt v= getVolt();
		return convertVolt(v,10);
	}

	@Override
	public Volt get3Volt() {
		Volt v= getVolt();
		return convertVolt(v,40);
	}
	
	private Volt convertVolt(Volt v, int i) {
		return new Volt(v.getVolts()/i);
	}

}

适配器设计模式 – 对象适配器实现

这是我们适配器的对象适配器实现。

package com.Olivia.design.adapter;

// 使用组合实现适配器模式
public class SocketObjectAdapterImpl implements SocketAdapter{

	// 使用组合方式实现适配器模式
	private Socket sock = new Socket();
	
	@Override
	public Volt get120Volt() {
		return sock.getVolt();
	}

	@Override
	public Volt get12Volt() {
		Volt v= sock.getVolt();
		return convertVolt(v,10);
	}

	@Override
	public Volt get3Volt() {
		Volt v= sock.getVolt();
		return convertVolt(v,40);
	}
	
	private Volt convertVolt(Volt v, int i) {
		return new Volt(v.getVolts()/i);
	}

}

请注意,两种适配器实现几乎相同,并且它们都实现了SocketAdapter接口。适配器接口也可以是一个抽象类。以下是一个测试程序,用于使用我们的适配器设计模式实现。

package com.Olivia.design.test;

import com.Olivia.design.adapter.SocketAdapter;
import com.Olivia.design.adapter.SocketClassAdapterImpl;
import com.Olivia.design.adapter.SocketObjectAdapterImpl;
import com.Olivia.design.adapter.Volt;

// 适配器模式测试类
public class AdapterPatternTest {

	public static void main(String[] args) {
		
		testClassAdapter();
		testObjectAdapter();
	}

	private static void testObjectAdapter() {
		SocketAdapter sockAdapter = new SocketObjectAdapterImpl();
		Volt v3 = getVolt(sockAdapter,3);
		Volt v12 = getVolt(sockAdapter,12);
		Volt v120 = getVolt(sockAdapter,120);
		System.out.println("使用对象适配器获取3伏特="+v3.getVolts());
		System.out.println("使用对象适配器获取12伏特="+v12.getVolts());
		System.out.println("使用对象适配器获取120伏特="+v120.getVolts());
	}

	private static void testClassAdapter() {
		SocketAdapter sockAdapter = new SocketClassAdapterImpl();
		Volt v3 = getVolt(sockAdapter,3);
		Volt v12 = getVolt(sockAdapter,12);
		Volt v120 = getVolt(sockAdapter,120);
		System.out.println("使用类适配器获取3伏特="+v3.getVolts());
		System.out.println("使用类适配器获取12伏特="+v12.getVolts());
		System.out.println("使用类适配器获取120伏特="+v120.getVolts());
	}
	
	private static Volt getVolt(SocketAdapter sockAdapter, int i) {
		switch (i){
		case 3: return sockAdapter.get3Volt();
		case 12: return sockAdapter.get12Volt();
		case 120: return sockAdapter.get120Volt();
		default: return sockAdapter.get120Volt();
		}
	}
}

当我们运行以上测试程序时,我们得到以下输出结果。

使用类适配器获取3伏特=3
使用类适配器获取12伏特=12
使用类适配器获取120伏特=120
使用对象适配器获取3伏特=3
使用对象适配器获取12伏特=12
使用对象适配器获取120伏特=120

适配器设计模式类图

适配器设计模式在JDK中的示例

在JDK类中,我能轻松找到一些适配器设计模式的例子。

  • java.util.Arrays#asList()(将数组转换为列表)
  • java.io.InputStreamReader(InputStream)(返回一个Reader对象)
  • java.io.OutputStreamWriter(OutputStream)(返回一个Writer对象)

这就是关于Java中适配器设计模式的全部了。

bannerAds