概述
适配器模式,将一个类的接口转化成客户希望的另外一种接口。适配器模式也是一个常用的模式。
生活中最明显的例子就是:
1. 通过变压器对电力进行变压。此处的变压器就是一个适配器
2. 还有就是电脑中USB接口通过转化器转化为Type_C接口等。
适配器模式可分为:类适配器模式;对象适配器模式;接口适配器模式
应用场景
- 系统需要使用现有的类,而这些类的接口不符合系统的需要。
- 想要建立一个可以重复使用的类,用于与一些彼此之间没有太大关联的一些类,包括一些可能在将来引进的类一起工作。
- 需要一个统一的输出接口,而输入端的类型不可预知。
定义和结构
下面我们就以变压器为例:将高电压转化为低电压。我们的变压器相当于Adapter,高压电相当于输入源(src),低压电相当于输出源(dst)
类适配器模式
demo
高电压接口(HeightElectric )
package com.adapter;
/**
* @author xiang.wei
* @create 2018/4/10 14:41
*/
public interface HeightElectric {
/**
* 创建高电压
* @param inputElec 输入电压
*/
int createHeightElectric(int inputElec);
}
高电压实现类(HeightElectricImpl)
package com.adapter;
/**
* @author xiang.wei
* @create 2018/4/10 14:53
*/
public class HeightElectricImpl implements HeightElectric {
@Override
public int createHeightElectric(int inputElec) {
return inputElec;
}
}
低电压接口(LowElectric)
package com.adapter;
/**
* @author xiang.wei
* @create 2018/4/10 14:46
*/
public interface LowElectric {
/**
* 创建低电压
* @param inputElec 创建低电压
*/
void createLowElectric(int inputElec);
}
适配器类(Adapter)
package com.adapter.classAdapter;
import com.adapter.HeightElectricImpl;
import com.adapter.LowElectric;
/**
* @author xiang.wei
* @create 2018/4/10 14:41
*/
public class Adapter extends HeightElectricImpl implements LowElectric {
@Override
public void createLowElectric(int inputElec) {
int heightElt = createHeightElectric(inputElec);
int lowElt = heightElt - 100;
System.out.println("输出电压为="+lowElt);
}
}
UML 类图
小结:类适配器模式需要继承HeightElectricImpl
类,这就将HeightElectricImpl
类的方法暴露出来了,也增加了使用成本。
同样,它也可以根据需求重写HeightElectricImpl
类中的方法,
由于Java单继承,所以dst
必须为接口。
对象适配器模式(常用)
与类适配器模式不同的是Adapter
类和Client
类
适配器类(Adapter),这次不再是继承HeightElectricImpl
类,而是持有HeightElectricImpl
类,以解决兼容性问题。
根据”合成复用原则”,在系统中尽量使用关联关系来替代继承关系,因此大部分结构型模式都是对象结构型模式。
package com.adapter.objectAdapter;
import com.adapter.HeightElectric;
import com.adapter.HeightElectricImpl;
import com.adapter.LowElectric;
/**
* @author xiang.wei
* @create 2018/4/10 14:41
*/
public class Adapter implements LowElectric {
private HeightElectric heightElectric;
public Adapter(HeightElectric heightElectric) {
this.heightElectric = heightElectric;
}
@Override
public void createLowElectric(int inputElec) {
int heightElt = heightElectric.createHeightElectric(inputElec);
int lowElt = heightElt - 100;
System.out.println("输出电压为="+lowElt);
}
}
Client类
package com.adapter.objectAdapter;
import com.adapter.HeightElectricImpl;
import com.adapter.LowElectric;
/**
* @author xiang.wei
* @create 2018/4/10 14:56
*/
public class Client {
public static void main(String[] args) {
LowElectric lowElectric = new Adapter(new HeightElectricImpl());
lowElectric.createLowElectric(300);
}
}
UML类图
小结:对象适配器和类适配器其实是同一种思想。只不过实现方式不同。
根据合成复用原则,组合大于继承,
所以它解决了类适配器必须继承src的局限性问题,也不再强求dst必须是接口。同样的它使用成本更低,更灵活。
接口适配器模式
接口适配器模式又称为缺省适配器模式,它的主要应用场景是在我们需要使用一个接口中的某几个方法时,我们可以写一个抽象类,其他无用的方法可以将让其空实现。子类可以重写需要的方法。
抽象的适配器(AbstractAdapter)
package com.adapter.interfaceAdapter;
/**
* @author xiang.wei
* @create 2018/4/10 14:41
*/
public abstract class AbstractAdapter implements LowElectricNew {
@Override
public void createLowElectric(int inputElec) {
}
@Override
public void showLowElectric() {
}
@Override
public void shutdowElectric() {
}
}
具体适配器(SonAdapter)
package com.adapter.interfaceAdapter;
import com.adapter.HeightElectric;
/**
* @author xiang.wei
* @create 2018/4/10 15:39
*/
public class SonAdapter extends AbstractAdapter {
private HeightElectric heightElectric;
public SonAdapter(HeightElectric heightElectric) {
this.heightElectric = heightElectric;
}
@Override
public void createLowElectric(int inputElec) {
int heightElt = heightElectric.createHeightElectric(inputElec);
int lowElt = heightElt - 100;
System.out.println("输出电压为="+lowElt);
}
}
低电压类(LowElectricNew)
package com.adapter.interfaceAdapter;
/**
* @author xiang.wei
* @create 2018/4/10 14:46
*/
public interface LowElectricNew {
/**
* 创建低电压
* @param inputElec 创建低电压
*/
void createLowElectric(int inputElec);
void showLowElectric();
void shutdowElectric();
}
客户端类(Client)
package com.adapter.interfaceAdapter;
import com.adapter.HeightElectricImpl;
/**
* @author xiang.wei
* @create 2018/4/10 14:56
*/
public class Client {
public static void main(String[] args) {
LowElectricNew lowElectricNew = new SonAdapter(new HeightElectricImpl());
lowElectricNew.createLowElectric(300);
}
}
小结:接口适配器模式令程序更加简洁明了。
总结
三种命名方式,是根据 src是以怎样的形式给到Adapter(在Adapter里的形式)来命名的。
类适配器,以类给到,在Adapter里,就是将src当做类,继承,
对象适配器,以对象给到,在Adapter里,将src作为一个对象,持有。
接口适配器,以接口给到,在Adapter里,将src作为一个接口,实现。