Zer0e's Blog

设计模式之适配器模式

字数统计: 833阅读时长: 3 min
2020/08/22 Share

前言

好久没写这个系列,趁着休息时间今天来讲讲适配器模式。

正文

概念

适配器模式属于结构型模式,这种设计模式解决的问题是原本由于接口不兼容而不能工作的类可以在一起工作。适配器模式与装饰模式很像,是定义一个包装类,来包装我们所需要适配的类,改变它的接口。但和装饰模式不同的是,包装类不改变原有类的功能,只是改变它的接口。
那运用的场景有:

  • 电压问题,国外与国内的家用电电压不同,导致进口电器需要适配器转换电压。
  • 在linux上运行windows程序,需要一个适配平台来实现。

实现

就用上面的第一个例子我们来讲讲这个模式。
首先我们创建原有的类,即国内都是220v的插座。

1
2
3
4
5
public class PowerSocket220V {
public void output_220v(){
System.out.println("输出220v");
}
}

接着我们创建适配器继承于这个类

1
2
3
4
5
6
7
8
public class PowerAdapter220V extends PowerSocket220V {
public void Convert_110V(){
//获取220V的输入
this.output_220v();
//进行转换
System.out.println("输出110V");
}
}

以上就是一个简单例子,即我没有改变原有类的功能,只是改变原有类的接口,使得可以正常工作。
那具体来说适配模式需要以下几个类:
1.一个已存在并且要适配的类,即原类。

1
2
3
4
5
public class Adaptee {
public void adapteeRequest() {
System.out.println("原类中的方法");
}
}

2.需要的目标接口,可以通过实现这个接口来增加接口

1
2
3
public interface Target {
void request();
}

3.适配器类,继承于原类,并且实现了目标接口中的方法。

1
2
3
4
5
6
7
8
9
public class Adapter extends Adaptee implements Target{
@Override
public void request() {
//do something
super.adapteeRequest();
//do something
}
}

或者我们可以在适配器中实例化原类,不继承原类。

1
2
3
4
5
6
7
8
9
10
public class Adapter implements Target{
private Adaptee adaptee = new Adaptee();

@Override
public void request() {
//do something
adaptee.adapteeRequest();
//do something
}
}

优缺点

那适配器模式的优点呢,是原类与适配类解耦,无需改变原类的结构。并且增加了类的复用与透明度,怎么说呢,由于适配类中的封装对客户端是可见的,所以是透明的。至于类的复用,原类可能实现十分复杂无法直接修改,类似于祖传代码,但是使用复杂,有了适配器模式就可以对原有类进行适配,所以就提高了它的复用性。
那缺点在于如果一个大型系统使用了很多适配器,那会十分杂乱,例如明明调用的是A接口但是内部却是调用B接口来实现。其次是像Java这种语言,不支持多继承,所以一次只能适配一个适配者类。

总结

综上所述,这个模式的场景是需要使用的原有的类,但这些类的接口不太符合系统需求,或者说是调用条件过于繁琐。但当系统逐渐扩大,过多的适配器会导致维护成本增加,所以如果不是十分必要,可以直接进行重构,而不是使用适配器。

CATALOG
  1. 1. 前言
  2. 2. 正文
    1. 2.1. 概念
    2. 2.2. 实现
    3. 2.3. 优缺点
  3. 3. 总结