概述
适配器模式,将一个类的接口转化成客户希望的另外一种接口。适配器模式也是一个常用的模式。
生活中最明显的例子就是:
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作为一个接口,实现。
参考
https://blog.csdn.net/zxt0601/article/details/52848004