概述
在生活中如果两个不同语言的人怎么沟通呢?翻译器。电源有二相插座,但是你是三相插头,那你怎么充电呢?插座适配器。电脑要在不同的国家使用,但是每个国家的电压标准不一样,那你怎么使用呢?电源适配器。这些物品就是我们适配器模式中的适配器。
概念
适配器模式定义:适配器模式将一个类的接口,转换成客户期望的另一个接口,使得原本由于接口不兼容而不能一起工作的那些类可以在一起工作
Client:客户端
Target:目标接口
Adapter:适配器
Adaptee:被适配类
在我们适用ListView的时候就是使用了适配器模式
适配器模式代码实现
我们就用插座适配器来举例吧。那我们的客户端是什么呢?电脑,目标接口:三相接口,适配器:电源适配器,被适配类:二相电流。
ThreePlugIf.java
package com.xjh.adapter;
/*
* 三相插座接口(被适配类)
*/
public interface ThreePlugIf {
//使用三相电流供电
public void powerWithThree();
}
GBTwoPlug.java
package com.xjh.adapter;
/*
* 使用国标二相电流(目标接口)
*/
public class GBTwoPlug {
//使用二相电流供电
public void powerWithTwo() {
System.out.println("使用二相电流供电");
}
}
我们让适配器实现ThreePlugIf接口,然后在内部拥有GBTwoPlug的引用(初始化时传入),在ThreePlugIf接口的powerWithThree方法中调用GBTwoPlug的powerWithTwo方法。
TwoPlugAdapter.java
package com.xjh.adapter;
/**
* 二相转三相的插座适配器
* @author Gin
*
*/
public class TwoPlugAdapter implements ThreePlugIf {
private GBTwoPlug plug;
public TwoPlugAdapter(GBTwoPlug plug) {
this.plug = plug;
}
@Override
public void powerWithThree() {
// TODO Auto-generated method stub
System.out.println("通过转换");
plug.powerWithTwo();
}
}
NoteBook.java
package com.xjh.adapter;
/**
* 客户端
* @author Gin
*
*/
public class NoteBook {
private ThreePlugIf plug;
public NoteBook(ThreePlugIf plug) {
this.plug = plug;
}
//使用插座充电
public void charge() {
plug.powerWithThree();
}
}
通过父类引用可以指向子类对象的特点实现三相接口使用二相插座。
Test.java
package com.xjh.adapter;
public class Test {
public static void main(String[] args) {
// TODO Auto-generated method stub
GBTwoPlug two = new GBTwoPlug();
ThreePlugIf plug = new TwoPlugAdapter(two);
NoteBook nb = new NoteBook(plug);
nb.charge();
}
}
这样我们通过适配器的转换就能够使得效果的到实现了,这就是我们通过组合实现适配器模式的过程。
采用组合方式实现的适配器称为对象适配器,特点:把“被适配者”作为一个对象组合到适配器类中,以修改目标接口包装被适配类。
那如果我们要用继承怎么实现呢?就是继承至被适配者,并且实现目标接口。
TwoPlugAdapterExtends.java
package com.xjh.adapter;
/**
* 采用继承方式的插座适配器
* @author Gin
*
*/
public class TwoPlugAdapterExtends extends GBTwoPlug implements ThreePlugIf {
@Override
public void powerWithThree() {
// TODO Auto-generated method stub
System.out.println("借助继承适配器");
this.powerWithTwo();
}
}
然后我们总结new出这个Adapter就可以了。
Test.java
package com.xjh.adapter;
public class Test {
public static void main(String[] args) {
// TODO Auto-generated method stub
GBTwoPlug two = new GBTwoPlug();
ThreePlugIf plug = new TwoPlugAdapterExtends();
NoteBook nb = new NoteBook(plug);
nb.charge();
}
}
通过继承的方式实现适配器称为类适配器,特点:通过多重继承不兼容接口,实现对目标接口的匹配,单一的为某个类而实现适配。
但是这两种的实现是有什么区别呢,通过对象适配器实现的服务于被适配类的所有子类,但是类适配器模式通过多重继承不兼容接口,实现对目标接口的匹配,单一的为某个类而实现适配的这样一种模式。
优点
- 透明:通过适配器,客户端可以调用同一接口,因而对客户端来说是透明的
- 重用:复用了现存的类,解决了现存类和复用环境要求不一致的问题
- 低耦合:将目标类和适配者类解耦,通过引入一个适配器类重用现有的适配者类,而无需修改原有代码。