Java设计模式:适配器模式

适配器模式基本介绍

介绍一个生活中的常例子:
你去日本旅游,发现自己的手机并不能在日本供电插座上充电,这是国家采用的用电标准不一致的问题而导致的。

例如:一些常见国家的使用电压:
使用110V:日本、韩国、菲律宾、法国、俄罗斯、西班牙、加拿大、墨西哥、美国等。

使用220V:印尼、印度、马来西亚、新加坡、泰国、土耳其、越南、奥地利、比利时、保加利亚、白俄罗斯、捷克、俄罗斯、丹麦、芬兰、德国、希腊、匈牙利、冰岛、爱尔兰、意大利、荷兰、挪威、波兰、葡萄牙、罗马尼亚、巴西、瑞典、新西兰、澳大利亚等。

在上下两类中的国家由于采用用电标准不一致,个人需要使用转换器(converter)来转换成自己的电子产品所采用的用电标准。
在这里起作用的转换器也可以称为适配器(adapter),基于这种生活场景,我们来介绍一下适配器模式:

适配器模式是作为两个不兼容的接口之间的桥梁。这种类型的设计模式属于结构型模式,它结合了两个独立接口的功能
主要有三类:类适配器模式、对象适配器模式、接口适配器模式。

一、类适配器

UML类图如下:
在这里插入图片描述
从上到下开始:
定义一个目标类的接口:

//目标类,作为接口
public interface ITargetVoltage {
    public void outPut220();
}

这里是具体目标类,假设为中国等国家的220V插座:

//具体目标类
public class ConcreteTargetVoltage implements ITargetVoltage {
    @Override
    public void outPut220() {
        System.out.println("220V插座");
    }
}

被适配类,注意是"被",为了方便说明,这里假设为日本等国家的110V电压插座:

//被适配类
public class AdapteeVoltage {
    public void outPut110(){
        System.out.print("110V插座");
    }
}

适配器类,在这个适配器类中,我们需要完成从被适配类到目标类的一系列转换操作,这里简单写为字符串输出代表已经经过操作

//适配器
public class Adapter extends AdapteeVoltage implements ITargetVoltage {
    @Override
    public void outPut220() {
    	//调用父类(被适配器类方法),在这里理解为拿到110V插座
        super.outPut110();
        //进行转换
        System.out.print("->进入适配器内部转换->");
        //得到输出
        System.out.print("输出220V");
    }
}

客户端调用:

public class Client {
    public static void main(String[] args) {
    	//先拿个国内220V插座(目标类)验证一下
        ITargetVoltage iVoltage220 = new ConcreteTargetVoltage();
        iVoltage220.outPut220();
		//通过适配器(集成了被适配类在里面)
		//按当前例子来说就是转换器和插座已经放在一起了
        ITargetVoltage iTargetVoltage = new Adapter();
        iTargetVoltage.outPut220();
    }
}

输出结果:

220V插座
110V插座->进入适配器内部转换->输出220V

客户端分别调用了目标类的具体实现类(这里表现为220V插座)和适配器类(这里表现为继承110V插座外加上实现220V插座的功能),通过调用其目标类接口的重写方法,返回了需要得到的目标类的结果(220V电压),于是我们的任何产品都可以通过这个适配器使用了。

二、对象适配器

这种方式与上述基本相同,只是关联方式变成了聚合,即在适配器类里声明被适配类作为其属性存在,并且通过构造器给与初始化:

//适配器
public class Adapter implements ITargetVoltage {
    //关联关系——聚合
    private AdapteeVoltage adapteeVoltage;
    public Adapter(AdapteeVoltage adapteeVoltage) {
        this.adapteeVoltage = adapteeVoltage;
    }
    @Override
    public void outPut220() {
        adapteeVoltage.outPut110();
        System.out.print("->进入适配器内部转换->");
        System.out.print("输出220V");
    }
}

相应的客户端的调用需要稍微改变:

public class Client {
    public static void main(String[] args) {
        ITargetVoltage iVoltage220 = new ConcreteTargetVoltage();
        iVoltage220.outPut220();
		//在适配器类里传入被适配类的对象
        ITargetVoltage iTargetVoltage = new Adapter(new AdapteeVoltage());
        iTargetVoltage.outPut220();
    }
}
三、接口适配器

这里假设一个场景,相信大家都见过万能充电接口,就是一条主充电线中分出来三种充电线分别为:Micro-USB、Type-C、Lightning,对应安卓、Type-C、苹果接口,就是一种多功能充电线。
同样,假如目标类可以有多种情况:

public interface MultiTarget {
    public void Micro_USB();
    public void TypeC();
    public void Lightning();
}

抽象实现类,不提供具体的实现方法:

public abstract class AbstractAdapter implements MultiTarget{
    @Override
    public void Micro_USB() {
    }
    @Override
    public void TypeC() {
    }
    @Override
    public void Lightning() {
    }
}

在实例化适配器的时候可以自定义想要的适配器:

public class Client {
    public static void main(String[] args) {
        //自定义适配器
        AbstractAdapter abstractAdapter = new AbstractAdapter(){
            @Override
            public void Micro_USB() {
                System.out.println("安卓充电接口");
            }
        };
    }
}

总结

①三种命名方式,是根据 目标是以怎样的形式给到Adapter(在Adapter里的形式)来命名的。

类适配器:以类给到,在Adapter里,就是将src当做类,继承;
对象适配器:以对象给到,在Adapter里,将src作为一个对象属性;
接口适配器:以接口给到,在Adapter里,将src作为一个接口,实现。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值