适配器模式在软件开发中其实是一个极其常见的模式,该模式的功能是使两个并不兼容的接口能够共同工作。很多时候我们都在有意无意的使用这个模式。
因为两个接口并不能兼容,所以适配器的任务就是对数据或者对象进行适配,让调用接口能够使用另一接口产生的结果。其中进行适配工作的对象,就是适配器。
很多设计模式教科书都喜欢用读卡器进行举例:手机用户常用的tf卡是不能插到电脑上工作的,而是需要插在读卡器上,然后接驳到电脑的USB端口上,这样就能进行数据处理工作了;同样的例子还有电源的转换器,美国的电压一般是110V,而中国大陆是220V,如果将美国标准的电器直接插到大陆的插座上使用,势必要出现电压过高被烧毁的结果,这时候就需要一个电压的转换器,将220V的电压转换为110V进行使用。这些,都是适配模式以及适配器的例子。
本文以一个简单的例子进行举例,目前有一个能产生用户列表的方法,有三个打印用户信息的方法希望能调用这个接口,但是这三个方法均不能接受列表格式的数据,则需要一个适配器将数据类型进行适配之后,传递给这个方法使用,代码如下:
package dp.adapter;
import java.util.ArrayList;
import java.util.List;
public class UsersManager{
/*
* 该方法只能生成用户名的列表,这样的数据结构不能被另外三个方法接受(这三个调用方法分别需要,数组,Vector,用竖线分割的字符串)
*/
public List<String> getUsersNamesList(){
List<String> usersNamesList = new ArrayList<String>();
usersNamesList.add("Jerry");
usersNamesList.add("Rich");
usersNamesList.add("John");
usersNamesList.add("Paul");
usersNamesList.add("Mark");
usersNamesList.add("Tom");
return usersNamesList;
}
}
package dp.adapter;
import java.util.Vector;
/*
* 适配器接口
*/
public interface UsersManagerAdapter{
public String[] getUsersNamesArray();
public Vector<String> getUsersNamesVector();
public String getUsersNamesSeperatedbyLine();
}
package dp.adapter;
import java.util.List;
import java.util.Vector;
/*
* 适配器能够为调用者适配出合适的数据结构
*/
public class UsersManagerAdapterImpl implements UsersManagerAdapter {
UsersManager usersManager = new UsersManager();
@Override
public String[] getUsersNamesArray() {
List<String> list = usersManager.getUsersNamesList();
String names[] = null;
if(list!=null && list.size()>0){
names = new String[list.size()];
for( int i=0;i<list.size();i++){
names[i] = list.get(i);
}
}
return names;
}
@Override
public Vector<String> getUsersNamesVector() {
Vector<String> usersVector = new Vector<>();
List<String> list = usersManager.getUsersNamesList();
if (list != null && list.size() > 0) {
for (int i = 0; i < list.size(); i++) {
usersVector.add(list.get(i));
}
}
return usersVector;
}
@Override
public String getUsersNamesSeperatedbyLine() {
List<String> list = usersManager.getUsersNamesList();
StringBuffer usersNamesString = new StringBuffer();
if (list != null && list.size() > 0) {
for (int i = 0; i < list.size(); i++) {
usersNamesString.append(list.get(i)).append("|");
}
}
return usersNamesString.toString();
}
}
package dp.adapter;
import java.util.Vector;
public class Main {
public static void main(String args[]) {
UsersManagerAdapter usersManagerAdapter = new UsersManagerAdapterImpl();
Main main = new Main();
System.out.println("-----------------------");
main.usersNamesArrayPrinter(usersManagerAdapter.getUsersNamesArray());
System.out.println("-----------------------");
main.usersVectorPrinter(usersManagerAdapter.getUsersNamesVector());
System.out.println("-----------------------");
main.usersStringPrinter(usersManagerAdapter.getUsersNamesSeperatedbyLine());
}
public void usersNamesArrayPrinter(String namesArrays[]) {
if (namesArrays != null) {
for (int i = 0; i < namesArrays.length; i++) {
System.out.println(namesArrays[i]);
}
}
}
public void usersVectorPrinter(Vector<String> namesVector) {
if (namesVector != null) {
for (int i = 0; i < namesVector.size(); i++) {
System.out.println(namesVector.get(i));
}
}
}
public void usersStringPrinter(String usersNames) {
if (usersNames != null) {
System.out.println(usersNames);
}
}
}
运行结果:
-----------------------
Jerry
Rich
John
Paul
Mark
Tom
-----------------------
Jerry
Rich
John
Paul
Mark
Tom
-----------------------
Jerry|Rich|John|Paul|Mark|Tom|
从运行结果可见,三个方法能够调用适配器转换过来的数据然后进行正常的打印。
总结:适配器模式在日常开发尤其是代码重构过程中非常常见,很多时候我们都有意无意的在使用该模式,毕竟很多旧的接口和方法返回的数据并不能适应新的接口调用,常常需要对数据进行适配。