介绍
适配器模式(Adapter Pattern)是作为两个不兼容的接口之间的桥梁。这种类型的设计模式属于结构型模式,它结合了两个独立接口的功能。
这种模式涉及到一个单一的类,该类负责加入独立的或不兼容的接口功能。举个真实的例子,读卡器是作为内存卡和笔记本之间的适配器。您将内存卡插入读卡器,再将读卡器插入笔记本,这样就可以通过笔记本来读取内存卡。
分类
接口适配器
示例一
举一个现有的例子,比如你想把Enumeration适配成Iterator,此时必须要明白几个基础概念,或者说是明确你的适配后目标和被适配的对象。
- 目标:Iterator;
- 对象:Enumeration;
做法:定义一个适配器,实现你的目标,组合被适配的对象。
package com.silence.mode.struct.adapter;
import java.util.Enumeration;
import java.util.Iterator;
public class EnumerationIteratorAdapter implements Iterator {
Enumeration enumeration;
public EnumerationIteratorAdapter(Enumeration enumeration) {
this.enumeration = enumeration;
}
public boolean hasNext() {
return enumeration.hasMoreElements();
}
public Object next() {
return enumeration.nextElement();
}
public void remove() {
}
}
示例二
大家可能都遇到过一种困扰,比如实现一个接口,而在这个众多接口方法中我们只需要使用其中一两个,一般的做法就是只实现其中这一两个业务逻辑,其他默认实现。但是这样一来就会出现很多冗余的方法,看起来太不协调,在一些主流的框架里面都会出现一些AbstractXXX的默认实现某个或者某些接口,这些实现逻辑基本上符合我们这个示例二所讲的实现方法。
再举一个例子,比如一般Filter都会有如下几个方法:
package com.silence.mode.struct.adapter.inter_face;
public interface AnyFilter {
void init();
void doFilter();
void destroy();
}
一般情况下我们可能只需要实现其中的doFilter(),那么我们就要在代码中冗余其它两个方法,但是如果此时我们创建一个AbstractXXX来默认实现一下其中的方法:
package com.silence.mode.struct.adapter.inter_face;
public class AbstractFilter implements AnyFilter {
@Override
public void init() {
System.out.println("Default init!");
}
@Override
public void doFilter() {
System.out.println("Default doFilter!");
}
@Override
public void destroy() {
System.out.println("Default destroy!");
}
}
这样一来,后续开发人员只需要实现AbstractFilter中的doFilter(),而不需要实现其它两个方法的业务逻辑即可完成我们的预期:
package com.silence.mode.struct.adapter.inter_face;
public class FilterImpl extends AbstractFilter {
@Override
public void doFilter() {
System.out.println("FilterImpl doFilter!");
}
}
对象适配器
不知道大家经历没有经历过这样一个时期,就是插头上面套个插头,或者是三相转两相或者两相转三相的时代。当然现如今我们已经不需要这么做了,我们拥有了插线板~,但是下面我举得这个例子就是那个时代的一个写照!
我有个冰箱,是三相插头的,但是我墙上的插板只有一个两相的插座,怎么办?
首先看看两相插头是如何工作的:
package com.silence.mode.struct.adapter.object;
public interface TwoPhasePlug {
void workWithTwoPlug(int plugs);
}
package com.silence.mode.struct.adapter.object.impl;
import com.silence.mode.struct.adapter.object.TwoPhasePlug;
public class RoundHeadTwoPhasePlug implements TwoPhasePlug {
@Override
public void workWithTwoPlug(int plugs) {
System.out.println("两相圆插头拥有" + plugs + "个插头!");
}
}
然后我有个三相插头的电器:
package com.silence.mode.struct.adapter.object;
public class ThreePhasePlug {
public void workWithThreePlug(int plugs) {
System.out.println("三相圆插头拥有" + plugs + "个插头!");
}
}
下面我就需要一个插头转换器:
package com.silence.mode.struct.adapter.object;
/**
* Created by Silence on 2018/6/12.
*/
public class Three2TwoPlugAdapter implements TwoPhasePlug {
private ThreePhasePlug threePhasePlug;
public Three2TwoPlugAdapter(ThreePhasePlug threePhasePlug) {
this.threePhasePlug = threePhasePlug;
}
@Override
public void workWithTwoPlug(int plugs) {
plugs = plugs - 1;
System.out.println("三相->两相转换器!");
threePhasePlug.workWithThreePlug(plugs);
}
}
这个示例中使用了适配器拥有源的一个实例的方式,也就是组合的方式诠释了转换器的实现原理,还有一种就是继承的方式,由于设计模式一个很重要的思想就是多用组合少用继承,因此我摒弃了最后一种方式也就是继承的方式,也被称为类适配器。