适配器模式——得心应手的“粘合剂”

适配器模式在日常开发中使用率极高,从代码中随处可见的Adapter就可以看出来。在Android中,ListView,GridView到现在最新的RecyclerView都需要使用Adapter,并且在开发中我们遇到的优化问题,出错概率较大的地方也基本来自Adapter,这是一个让人又爱又恨的角色。

言归正传,适配器是将两个不兼容的类融合在一起,它有点像粘合剂,将不同的东西通过一种转换使得它们能够协作起来。例如,经常碰到要在两个没有关系的类型之间进行交互。第一个解决方法时修改各自的接口,但是如果没有源代码要在或者我们不愿意为了一个应用而修改各自的接口,此时我们往往需要使用一个Adapter,在这两种接口之间创建一个接口,这个Adapter会将这两个接口进行兼容,在不修改原有代码的情况下满足需求。

适配器模式把一个类的接口变换陈客户端所期待的另一种接口,从而使原本因接口不匹配而无法再一起工作的两个类能够子啊一起工作。


模式中的角色

 目标接口(Target):客户所期待的接口。目标可以是具体的或抽象的类,也可以是接口。
 需要适配的类(Adaptee):需要适配的类或适配者类。
 适配器(Adapter):通过包装一个需要适配的对象,把原接口转换成目标接口。

实现方式主要有两种:

类的是适配器模式

对象适配器模式


1)类的是适配器模式

UML类图如图所示



类的适配器模式采用继承方式实现

Adaptee.java

package com.test.adapter;

public class Adaptee {
	public void specificRequest() {
		System.out.println("被适配类...的特异功能");
	}
}
Target.java

package com.test.adapter;

public interface Target {
	public void request();  
}
ConcreteTarget.java

package com.test.adapter;

public class ConcreteTarget implements Target{

	@Override
	public void request() {
		// TODO Auto-generated method stub
		 System.out.println("普通类、、、没有特异功能");  
	}

}
Adapter.java

package com.test.adapter;

public class Adapter extends Adaptee implements Target{

	@Override
	public void request() {
		// TODO Auto-generated method stub
		super.specificRequest();  
	}

}

最后是客户端

Client.java

package com.test.adapter;

public class Client {
	public static void main(String[] args) {
		// 使用普通功能类
		Target concreteTarget = new ConcreteTarget();
		concreteTarget.request();

		// 使用特殊功能类,即适配类
		Target adapter = new Adapter();
		adapter.request();
	}
}
运行结果如下

普通类、、、没有特异功能
被适配类...的特异功能




2)对象适配器模式
UML类图如图所示



与类的适配器模式不同的是,对象的适配器模式不是使用继承关系连接到Adaptee类,而是使用代理关系连接到Adaotee类。

此时只需要修改Adapter.java

public class Adapter implements Target{
	// 直接关联被适配类  
    private Adaptee adaptee;  
      
    // 可以通过构造函数传入具体需要适配的被适配类对象  
    public Adapter (Adaptee adaptee) {  
        this.adaptee = adaptee;  
    }  
	@Override
	public void request() {
		// TODO Auto-generated method stub
		adaptee.specificRequest();
	}
	
}

客户端也要稍微修改一下

public class Client {
	public static void main(String[] args) {
		// 使用普通功能类
		Target concreteTarget = new ConcreteTarget();
		concreteTarget.request();

		// 使用特殊功能类,即适配类
		Target adapter = new Adapter(new Adaptee());
		adapter.request();
	}
}


只是new Adapter(new Adaptee());构造方法传入了新的参数,其它一样的,运行结果也是一样的。

从类图中我们也知道需要修改的只不过就是 Adapter 类的内部结构,即 Adapter 自身必须先拥有一个被适配类的对象,再把具体的特殊功能委托给这个对象来实现。使用对象适配器模式,可以使得 Adapter 类(适配类)根据传入的 Adaptee 对象达到适配多个不同被适配类的功能,当然,此时我们可以为多个被适配类提取出一个接口或抽象类。这样看起来的话,似乎对象适配器模式更加灵活一点。


总结

Adapter模式的经典实现在于将原本不兼容的接口融合在一起,使之能够很好的进行合作,但是在实际开发中,Adapter模式也有灵活的实现,可以稍微修改一下。例如ListView中的BaseAdapter,SimpleAdapter就稍微做了一下修改。

优点:

1)更好的复用性

2)更好的扩展性

缺点:

过多的使用适配器,会让系统凌乱,不易整体把握。








  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值