设计模式--适配器模式(Adapter Pattern)

本文的来源是《Effective Java Second Edition》 中第六页提到的适配器模式相关内容的一个学习笔记,如有不正确的地方,欢迎批评与指正,本人不胜感激!


适配器模式(Adapter Pattern)的主要作用是用于新旧接口之间的适配,这个与我们生活中的电源插头适配器是非常类似的。

比如你家里墙壁上只有一个三孔的插座,但是现在有一个两相的插头需要插进去,现在的你总不能拆了墙壁上三孔的插座吧 —— 这样子的代价也太大了。

这时候我们的电源适配器就闪耀的登场了

设计模式--适配器模式(Adapter Pattern)_第1张图片

这样我们就可以将该适配器三相的插头插入到插座,上面接入我们两相的插头了,就完成了适配的工作了。


首先我们整理一下我们拥有的物品:三孔接口,两孔接口,一个电源适配器,墙壁上的三孔插座,适配器上的两孔插座。

那么接下来我们就使用程序来实现我们的适配器模式吧。

三孔接口

package com.blog.pattern;

/**
 * @func 三孔接口.
 * @author 张俊强~
 * @time 2017/10/29 08:26
 *
 */
public interface ThreeHoleInter {
    public void threeHoleFunction();
}

两孔接口

package com.blog.pattern;

/**
 * @func 两孔接口.
 * @author 张俊强~
 * @time 2017/10/29 08:27
 */
public interface TwoHoleInter {

    public void twoHoleFunction();

}

墙壁上的三孔插座实现了三孔接口,并具备[ 给三相插头提供电源 ]的功能

package com.blog.pattern;

/**
 * @func 墙壁上的三孔插座.
 * @author 张俊强~
 * @time 2017/10/29 08:29
 */
public class ThreeHoleSocketImpl implements ThreeHoleInter {

    //三孔插座的功能是[ 给三相插头提供电源 ]
    @Override
    public void threeHoleFunction() {
        System.out.println("给三相插头提供电源!");
    }
}

适配器上的两孔插座实现了两孔接口,并具备[ 给两相插头提供电源 ]的功能

package com.blog.pattern;

/**
 * @func 适配器上的两孔插座.
 * @author 张俊强~
 * @time 2017/10/29 08:30
 */
public class TwoHoleSocketImpl implements TwoHoleInter {//实现了两孔接口的功能

    //适配器上的两孔插座的功能是[ 给两相插头提供电源 ]
    @Override
    public void twoHoleFunction() {
        System.out.println("给两相插头提供电源!");
    }
}

一个电源适配器

package com.blog.pattern;

/**
 * @func 电源适配器.
 * @author 张俊强~
 * @time 2017/10/29 08:31
 */
public class SocketAdapter implements ThreeHoleInter {//电源适配器实现了三孔的接口

    private TwoHoleInter twoHoleSocket;//组合的的两孔接口

    public SocketAdapter(TwoHoleInter twoHoleSocket){
        this.twoHoleSocket=twoHoleSocket;
    }

    @Override
    public void threeHoleFunction() {//对三孔接口的调用提供两孔接口的功能
        twoHoleSocket.twoHoleFunction();
    }
}

基本上所有的物品都用程序写好了,接下来我们就来测试一下这个适配器类吧!

    public static void main(String[] args){

        //两孔的插座(也可以是实现了两孔接口的其他各种插座)
        TwoHoleInter twoHoleInter=new TwoHoleSocketImpl();

        //给我们的适配器加上两孔的插座(也可以加上实现了两孔接口的其他各种插座)
        SocketAdapter socketAdapter=new SocketAdapter(twoHoleInter);

        //适配器调用三孔的接口给两相插头提供电源!
        socketAdapter.threeHoleFunction();//适配器调用三孔的接口
        // 输出信息: [ 给两相插头提供电源! ]

    }

以上就是一个适配器模式的例子了


其实适配器模式有两种:类适配 器和对象适配器
上面的是对象适配器(推荐使用),使用我们实例化的对象进行调用我们的目标功能。

    @Override
    public void threeHoleFunction() {
        //使用我们实例化的对象进行调用
        twoHoleSocket.twoHoleFunction();
    }

还有一种是类适配器,相对耦合度更高,不推荐使用
适配器的写法如下

package com.blog.pattern;

/**
 * @func 电源适配器(类适配器).
 * @author 张俊强~.
 * @time 2017/10/29 09:10.
 */
public class SocketAdapter extends TwoHoleSocketImpl implements ThreeHoleInter {

    //继承 TwoHoleSocketImpl 调用父类方法(继承类写死)
    @Override
    public void threeHoleFunction() {
        super.twoHoleFunction();
    }
}

这样测试类写法如下

    public static void main(String[] args){

        //实例化适配器
        SocketAdapter socketAdapter=new SocketAdapter();

        //适配器调用三孔的接口给两相插头提供电源!
        socketAdapter.threeHoleFunction();//适配器调用三孔的接口
        // 输出信息: [ 给两相插头提供电源! ]

    }

这样子的话就没办法自定义设置实现了两孔接口的其他插座。


参考资料
[1]. 一个示例让你明白适配器模式
[2]. 适配器模式原理

你可能感兴趣的:([,Effective,Java,Notes,],[,浅谈设计模式,])