适配器模式—类适配器、对象适配器、接口适配器(结构型)

        Adapter英文翻译是转换器、适配器、接头,从名字们就应该能很好的理解。就好比是一个转换头一样,比如去国外,很多时候我们中国带过去的电器插头就需要转换器,再比如内存卡跟电脑交互,很多时候就需要一张读卡器,此时读卡器充当的就是转换器、适配器的功能。

        适配器模式将一个类的接口适配成用户所期待的,一个适配器通常允许因为接口不兼容而不能一起工作的类能够在一起工作,于是需要适配器来解决这个兼容性问题。下面介绍一下三种经典适配器。

        类适配器:

        相信很多大学寝室的电力功率都是有限制的,比如最高只能800KW,有时候买了一只锅,可能锅的功率是1000KW,完了,不能用了。有办法可以用,我们知道,功率跟电压是成正比的,寝室电压是220V,要是能把电压降下来,功率其实也就降下来了,只是煮东西稍微慢了点而已。好的我们去买一个变压器,这里就相当于是适配器了,这个变压器油两个选择,可以变为110v,也可以变为55v,假设正常220v这只锅需要5分钟煮好,那么110v需要10分钟,55v需要20分钟,那我们下面通过代码来进行描述。

        首先我们寝室的电压是220v的,于是:

public class Voltage220{
    public int outPut220(){
        int voltage = 220;
        return voltage;
    }
}

        然后我们买回来一只锅:

public class Pot{
    public void start(int voltage){
        if(voltage == 110){
            System.out.println("电压" + voltage + "V,消耗10分钟煮好!");
        }else if(voltage == 55){
            System.out.println("电压" + voltage + "V,消耗20分钟煮好!");
        }else{
            System.out.println("电压" + voltage + "V,断电了,赶紧藏锅,宿管阿姨要来了!");
        }
    }

}

        我们此时知道直接使用会断电,于是再去校门口买个变压器,也就是我们的适配器,适配器有两个接口实现,一个实现110v,一个实现55v:

         

public interface Voltage110{
    int outPut100();
}
public interface Voltage55{
    int outPut55();
}
public class VoltageAdapter extends Voltage220 implements Voltage55,Voltage110{
    @Override
    public int outPut110(){
        int voltage = outPut220() / 2;
        return voltage;
    }


    @Override
    public int outPut55(){
        int voltage = outPut220() / 4;
        return voltage;
    }
}

        好了,什么都齐了,就差开始煮了,于是我们来个测试:

public class Test{
    public static void main(String[] args){
        //锅拿出来
        Pot pot = new Pot();
        //变压器拿出来,也就是适配器
        VoltageAdapter voltageAdapter = new VoltageAdapter();

        //选择用哪一个档位开始煮
        //110v来煮
        pot.start(voltageAdapter.outPut110());
        //55v来煮
        pot.start(voltageAdapter.outPut55());
        //作死,适配器选择初始位置,也就相当于选择不变档位一样
        pot.start(voltageAdapter.outPut220());
    }

}

        这就是类适配器的使用,我们可以看见,类适配器中,我们需要继承现在有的类,然后要适配某一个的化,得有它的接口,然后用适配器实现这个接口,这样才能完成整个适配过程。

        对象适配器:

        在实际中,我们用到最多的是对象适配器,因为Java是单继承多实现的,假设这个适配器本来需要继承一个东西,那么,就没办法进行类适配器了,这时候我们需要用到对象适配器。对象适配器其实很简单,也更符合面向对象的思维,具体就是在适配器里面建立一个对象。之前的代码我们只需要修改VoltageAdapter类和Test类即可:

public class VoltageAdapter implements Voltage55,Voltage110{
    
    public Voltage220 voltage220;

    public VoltageAdapter(){
        voltage220 = new Voltage220();
    }
    @Override
    public int outPut110(){
        int voltage = outPut220() / 2;
        return voltage;
    }


    @Override
    public int outPut55(){
        int voltage = outPut220() / 4;
        return voltage;
    }
}
public class Test{
    public static void main(String[] args){
        //锅拿出来
        Pot pot = new Pot();
        //变压器拿出来,也就是适配器
        VoltageAdapter voltageAdapter = new VoltageAdapter();

        //选择用哪一个档位开始煮
        //110v来煮
        pot.start(voltageAdapter.outPut110());
        //55v来煮
        pot.start(voltageAdapter.outPut55());
        //作死,适配器选择初始位置,也就相当于选择不变档位一样
        pot.start(voltageAdapter.voltage220.outPut220());
    }

}

        从这里我们看出对象适配器相对于类适配器的优势,我看很多其他人写的对象适配器是在适配器里面用一个有参构造来接收的对象,那样也不是不行,但是我个人觉得用一个无惨构造来new对象可能更好一点,我们不用再调用的时候再把对象再传进去,不用关心220v这个对象的创建,可能更符合一点。而且我们应该将220v这个属性设置为public,因为个人觉得适配器除了能帮我们转换以外,也是能够直接使用我们的原类的,也就是220v那个类,设置为private后,我们就不能使用了,这样我觉得不太符合适配器的含义。当然,求同存异,有其它建议也希望大家指出。

        接口适配器:

        接口适配器的话,就是写成接口来使用,我们可以不用去实现某个接口方法,只实现自己需要的。就好比现在转换器可以转换很多种电压,但是有些我们不需要,然后不实现它一样。我们之前的Pot、Voltae220类不变

        首先需要一个电压接口:

public interface VoltageInterface{
    int outPut5();

    int outPut10();

    int outPut55();

    int outPut110();
}

        接着使用一个抽象类去实现这个接口:

public abstract class AbstractClass implements VoltageInterface{
    @Override
    public int outPut5(){
        return 0;
    }
    @Override
    public int outPut10(){
        return 0;
    }
    @Override
    public int outPut55(){
        return 0;
    }
    @Override
    public int outPut110(){
        return 0;
    }

}

      然后我们买的变压器只实现了55和110的,即适配器只实现55和110的:

public class VoltageAdapter extends AbstractClass{
    public Voltage220 voltage220;

    public VoltageAdapter(){
        voltage220 = new Voltage220();
    }
    @Override
    public int outPut55(){
        int outPut = voltage220.outPut220 / 4;
        return outPut;
    }
    @Override
    public int outPut110(){
        int outPut = voltage220.outPut220 / 2;
        return outPut;
    }
}

        那么我们测试这样调用:

public class Test{
    public static void main(String[] args){
        //锅拿出来
        Pot pot = new Pot();
        //变压器拿出来,也就是适配器
        VoltageAdapter voltageAdapter = new VoltageAdapter();

        //选择用哪一个档位开始煮
        //110v来煮
        pot.start(voltageAdapter.outPut110());
        //55v来煮
        pot.start(voltageAdapter.outPut55());
        //作死,适配器选择初始位置,也就相当于选择不变档位一样
        pot.start(voltageAdapter.voltage220.outPut220());
    }

}

        对于接口适配器,我个人是这样理解的,我自己分析发现跟其他人的博客好像有点出入,大多数是将Voltage220这个类,即我们已经拥有的类这个对象放置在抽象接口中的,但我是放进适配器中的,因为我觉得是适配器在对这个已经拥有的类进行转换,而不是我们的抽象类在对其进行转换,目前我是这样理解的,感觉比较符合接口适配器模式的思想,如果有其它意见,还请指出。当然,我的Pot类,即锅这个类还不够完善,还应该加入0V的时候提醒未实现该适配器才更完善。

        对于以上三个经典适配器,在选择使用方面,个人比较推荐使用对象适配器,因为Java是单继承多实现的,继承毕竟只能继承一个,而实现没有容量限制,所以个人推荐对象适配器。

发布了165 篇原创文章 · 获赞 41 · 访问量 8万+

猜你喜欢

转载自blog.csdn.net/qq_41061437/article/details/100090684