"围观"设计模式(11)--结构型之适配器模式(Adapter Pattern)

Posted 低调的洋仔

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了"围观"设计模式(11)--结构型之适配器模式(Adapter Pattern)相关的知识,希望对你有一定的参考价值。

在设计模式中,适配器模式(英语:adapter pattern)有时候也称包装样式或者包装(wrapper)。将一个类的接口转接成用户所期待的。一个适配使得因接口不兼容而不能在一起工作的类工作在一起,做法是将类自己的接口包裹在一个已存在的类中。----WIKIPEDIA


个人理解

适配器模式:将两个不一致或者说无法直接使用的类或者接口通过适配器模式进行兼容,使得他们可以在一块使用。适配器模式在之前的项目中我是用于处理数据的不兼容的,对方的数据和我们的数据格式不完全一致,包括,类型的不一致和内容的不一致,类型的不一致比较容易解决,但是内容的不一致比如:对方的数据中存在一个id对应着俩值,而在我们的系统中,一个id只对应一个值,这样的话,显然没办法直接使用,而且,需要对对方的数据进行存储下来,进行了一定的设置后才会将数据存入我们的数据库中,我当时的解决办法是,将存入本地的id设为string类型,然后通过id_** ,id_标位 进行标识该值属于哪个id以及其代表的意义。为了实现这种目的我采用了适配器模式,对方传递的数据封装好,通过适配器将该封装好的对象转为我们可以进行本地存储的对象。


主要的代码如下(全部的代码可以进行下载:设计模式代码下载):

public class DataFrom {

	private int id;
	
	private int x;
	
	private int y;
}

public class DataInto {

	private String id;
	
	private int num;
}
使用适配器模式将From对象转化为多个Into的数据
public static List<DataInto> getTransferData(DataFrom dataFrom){
		if(dataIntoList != null && dataIntoList.size() > 0)
			dataIntoList.clear();
		
		DataInto dataIntoForX = new DataInto();
		dataIntoForX.setId(dataFrom.getId() + "_x");
		dataIntoForX.setNum(dataFrom.getX());
		dataIntoList.add(dataIntoForX);
		
		DataInto dataIntoForY = new DataInto();
		dataIntoForY.setId(dataFrom.getId() + "_y");
		dataIntoForY.setNum(dataFrom.getY());
		
		dataIntoList.add(dataIntoForY);
		return dataIntoList;
	}

参照设计模式之禅这本书再来看一个例子。

书中的例子是这样的,作者这边的数据是单个的属性,但是对方却是将一些属性进行了二次的封装,那么这种情况下,使用适配器模式使得这两者可以共同运作互不影响。


我在实际的写这个例子的时候,觉得这个例子不是很好,我又重新构造了这个例子,使得转换后直接转为对象进行返回,将对象作为一个整体去考虑问题。


其类图如下:

这里UserInfoTransfer类为中间的转换类,UserFrom类是对方的数据类。UserInfoInto为本方的数据的形式。

现在在对方的类中初始化部分的数据,代码如下所示:

public class UserInfoFrom implements UserInfoFromInterface{

	@Override
	public Map<String, String> getUserInfo() {
		Map<String, String> nameMap = new HashMap<String, String>();
		nameMap.put("wy", "wangyang");
		nameMap.put("w", "wang");
		return nameMap;
	}

	@Override
	public Map<String, String> getHomeAddress() {
		Map<String, String> addressMap = new HashMap<String, String>();
		addressMap.put("wy", "SH");
		addressMap.put("w", "S");
		return addressMap;
	}

}

本方的数据对应的类为:

public class UserInfoInto {

	private String userName;
	
	private String address;
}

适配器模式转换类代码如下所示:

public class UserInfoTransfer extends UserInfoFrom implements UserInfoIntoInterface{

	private Map<String, String> nameInfo = super.getUserInfo();
	private Map<String, String> addressInfo = super.getHomeAddress();
	
	@Override
	public UserInfoInto getUser() {
		UserInfoInto into = new UserInfoInto();
		into.setUserName(nameInfo.get("wy"));
		into.setAddress(addressInfo.get("wy"));
		
		return into;
	}
	
}

适配器的优点

1. 适配器模式可以让两个不是很一致的类在一起运行。

2. 更加灵活,如果有一天不想用适配器的时候,删掉这个适配器就可以了(前提是在其他的类中未调用这个适配器的类,否则也不能直接删除)。当发现业务变化,对方的数据或者类发生了变更的时候,可以通过更改适配器的类,来达到兼容的目的。


适配器模式注意事项

他不是为了解决正在开发中的问题,而是解决正在使用的项目的不兼容的问题。


源码地址:设计模式源码下载地址


以上是关于"围观"设计模式(11)--结构型之适配器模式(Adapter Pattern)的主要内容,如果未能解决你的问题,请参考以下文章

"围观"设计模式(15)--结构型之桥梁模式(Bridge Pattern)

"围观"设计模式(12)--结构型之代理模式(Proxy Pattern)

"围观"设计模式(14)--结构型之外观模式(Facade Pattern)

"围观"设计模式(17)--结构型之享元模式(Flyweight Pattern)

&quot;围观&quot;设计模式--里氏替换原则(LSP,Liskov Substitution Principle)

"围观"设计模式(22)--行为型之职责链模式(Chain Of Responsibility Pattern)