定义
适配器模式(Adapter Pattern):将一个类的接口转换成客户期望的另一个接口,适配器让原本接口不兼容的类可以相互合作。
适配器模式有类的适配器模式
和对象的适配器模式
两种不同的形式。
适配器模式优点
- 复用且不修改类 : 不改变现有类的基础上 , 提高类的复用性 , 透明性 ; 让现有类与目标类接口匹配 ;
- 降低耦合 : 目标类 ( 用户调用的接口所在类 ) 和 现有类 ( 被适配者 ) 解除耦合 , 降低了系统的耦合性 , 易于扩展维护;
- 符合开闭原则 : 用户调用适配器接口 , 只与适配器类进行交互 , 如果需要修改扩展 , 只需要修改适配器类即可 , 目标类和现有类各自都是相互独
立的 , 互不影响 ;
适配器模式缺点
- 增加复杂性 : 编写适配器类时 , 需要考虑全面 , 包括被适配者 和 目标类 , 系统复杂性会增加;
- 降低可读性 : 系统代码可读性降低 , 可维护性降低 ;
对象适配器
在对象适配器模式中,适配器与适配者之间是关联关系
(适配者是适配器的成员变量)。
结构图
- Target(目标抽象类):目标抽象类定义客户所需接口,可以是一个抽象类或接口,也可以是具体类。
- Adapter(适配器类):适配器可以调用另一个接口,作为一个转换器,对Adaptee和Target进行适配,适配器类是适配器模式的核心,在对象适配器中,
它通过继承(或者实现)Target并关联一个Adaptee对象使二者产生联系。
- Adaptee(适配者类):适配者即被适配的角色,它定义了一个已经存在的接口,这个接口需要适配,适配者类一般是一个具体类,包含了客户希望使用的
业务方法,在某些情况下可能没有适配者类的源代码。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
| package com.shjlone.designpattern.adapter.objectadapter;
public class ObjectAdapterTest { public static void main(String[] args) { TypeC typeC = new Phone(); MicroUsb microUsb = new Adapter(typeC); microUsb.microUsb(); } }
interface MicroUsb { public void microUsb(); }
interface TypeC { public void typeC(); }
class Phone implements TypeC { public void typeC() { System.out.println("Type-C接口"); } }
class Adapter implements MicroUsb { private TypeC typeC;
public Adapter(TypeC typeC) { this.typeC = typeC; }
@Override public void microUsb() { typeC.typeC(); } }
|
类适配器
在类适配器模式中,适配器与适配者之间是继承关系
。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
| package com.shjlone.designpattern.adapter.classadapter;
public class ClassAdapterTest {
public static void main(String[] args) { MicroUsb microUsb = new Adapter(); microUsb.microUsb(); } }
interface MicroUsb { public void microUsb(); }
interface TypeC { public void typeC(); }
class Phone implements TypeC { public void typeC() { System.out.println("Type-C接口"); } }
class Adapter extends Phone implements MicroUsb { public void microUsb() { typeC(); } }
|
缺省适配器模式(Default Adapter Pattern)
当不需要实现一个接口所提供的所有方法时,可先设计一个抽象类实现该接口,并为接口中每个方法提供一个默认实现(空方法),
那么该抽象类的子类可以选择性地覆盖父类的某些方法来实现需求,它适用于不想使用一个接口中的所有方法的情况,又称为单接口适配器模式。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50
| package com.shjlone.designpattern.adapter.defaultadapter;
public class DefaultAdapterTest { public static void main(String[] args) { TypecToVGA typecToVGA = new TypecToVGA(); typecToVGA.isTypeC(); typecToVGA.isVGA(); } }
interface AllPorts { public void isTypeC();
public void isVGA();
public void isHdmi(); }
abstract class Adapter implements AllPorts { @Override public void isTypeC() { }
@Override public void isVGA() { }
@Override public void isHdmi() { } }
class TypecToVGA extends Adapter { @Override public void isTypeC() { System.out.println("信号从TypeC接口进入"); }
@Override public void isVGA() { System.out.println("信号从VGA接口出"); } }
|
使用场景
- Java连接数据的JDBC工具
- List Arrays.asList(T[])
- InputStreamReader
- StringReader
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
|
public class StringReader extends Reader {
private String str; private int length; private int next = 0; private int mark = 0;
public StringReader(String s) { this.str = s; this.length = s.length(); } public int read() throws IOException { synchronized (lock) { ensureOpen(); if (next >= length) return -1; return str.charAt(next++); } } }
|
参考