适配器模式
定义
将一个类的接口变换成客户端所期待的另一种接口,从而使原本因接口不匹配而无法工作的两个类能够一起工作。
通用类图

在贴通用代码之前先来看一下这几个类所代表的含义。
-
Target 目标角色
这个类是我们所期望使用的,举个例子,比如家里通水管需要使用小口径的,我们所期待的是不管从外面接进来的是大口还是小口,我就是想使用小口的,这个小口就是目标。 -
Adapteree 源角色
这个类是我们所要转变的,也就是我们所说的从外面接入的这个大口水管。 -
Adapter 适配器
理所当然,这个类所充当的角色就是一个转换器,它一端连着目标角色,一端连着原角色,负责将两端连通。
通用代码
// 目标角色接口
public interface Target {
public abstract void request();
}
// 具体目标角色
public class ConcreteTarget implements Target {
@Override
public void request() {
// 目标角色所要执行的操作
}
}
// 源角色
public class Adapteree {
public void doSomething() {
// 源角色所执行的逻辑
}
}
// 适配器
public class Adapter extends Adapteree implements Target {
@Override
public void request() {
// 在这里完成转换,比如逻辑上的修改或者返回类型的转变等
super.doSomething();
}
}
// 客户端调用
public class Client {
public static void main(String[] args) {
Target target1 = new ConcreteTarget();
target1.request(); // 原来的业务逻辑
Target target2 = new Adapter();
target2.request(); // 修改过后的业务逻辑
}
}
这种通过继承关系的适配器称为类适配器,在实际中我们也会使用另一种扩展类型——对象适配器。对象适配器模式不通过继承关系,它是通过持有对象完成相关接口的转换的。打个比方,拿洗澡来说,夏天我们洗冷水澡,冬天洗热水澡,那么大部分人是喜欢适温的水。现在有热水的管子,也有冷水的管子,我们希望用一个水龙头就可以做到出温水,那么就可以通过一个三口转换器,一端连热水,一端连冷水,一端连水龙头。其实这个适配器用类适配器也可以做到,就是这个转换器继承三个类——热水、冷水、温水。但是随着源角色复杂之后,耦合度也就提高了,通过持有相应的对象可以灵活的设计和转换。
下面是扩展类图

public class Adapter extends Target {
private Adapteree1 e1;
private Adapteree2 e2;
public void request() {
e1.specifiRequest();
e2.specifiRequest();
……
// 不一定是在一个方法,可能要有多个方法完成转变
}
}
样例展示
描述
一个软件团队开发绘图系统,设计了圆对象(Circle)、矩形对象(Rectangle),线对象(Line)都支持Draw()函数,即可以通过Draw()函数绘制图形。为了加快项目进度,将角度对象(Angle)绘制功能交给了合作团队实现。但合作团队将角度对象绘制函数定为了DrawAngle()。绘图系统提供给用户后,用户不满意,希望能统一的调用,不用记太多命令。
样例类图

代码实现
// 定义图形接口
public interface Shape {
// 统一行为,可以画圆、矩形等
public void draw();
}
// 下面分别是画圆、矩形、线条类
public class Circle implements Shape {
@Override
public void draw() {
System.out.println("画一个圆");
}
}
public class Rectangle implements Shape{
@Override
public void draw() {
System.out.println("画一个矩形");
}
}
public class Line implements Shape {
@Override
public void draw() {
System.out.println("画一条线");
}
}
// 这是外包做的角度类
public class Angle {
public void drawAngle() {
System.out.println("画一个角度");
}
}
// 适配器
public class AngleAdapter extends Angle implements Shape {
@Override
public void draw() {
super.drawAngle();
}
}
// 客户端
public class Client {
public static void main(String[] args) {
Shape c = new Circle();
Shape r = new Rectangle();
Shape l = new Line();
Shape a = new AngleAdapter();
c.draw();
r.draw();
l.draw();
a.draw(); // 适配器将接口统一了
}
}
本文为《设计模式之禅》读后笔记总结
网友评论