Welcome everyone

适配器模式

设计模式 汪明鑫 807浏览 0评论

什么是适配器

适配器是一个接口转换器,它可以是一个独立的硬件接口设备,允许硬件或电子接口与其它硬件或电子接口相连,也可以是信息接口。比如:电源适配器、三角架基座转接部件、USB与串口的转接设备等。
USB又可以插鼠标、又可以插键盘、移动硬盘等,这就是适配器的功劳。
读卡器是作为内存卡和笔记本之间的适配器。您将内存卡插入读卡器,再将读卡器插入笔记本,这样就可以通过笔记本来读取内存卡。

认识适配器模式

适配器模式也是这个道理:
适配器模式(Adapter Pattern)是作为两个不兼容的接口之间的桥梁。
这种类型的设计模式属于结构型模式,它结合了两个独立接口的功能。
这种模式涉及到一个单一的类,该类负责加入独立的或不兼容的接口功能。
适配器模式将一个类的接口转换成客户希望的另一个接口。
适配器模式让那些接口不兼容的类可以一起工作。

 

适配器模式的别名为包装器(Wrapper)模式。

使用场景

值得注意的是适配器模式并不是在最开始做开发时需要考虑的

而是后续要做功能适配,考虑到接口之间的兼容需要用到的

以前的接口不适用了,但是需要原有类的功能

则直接在原有类上做适配,对原有类零修改

通过继承、组合的方式,做一层包装

适配器模式分类

 

类适配器(继承),对象适配器(组合),接口适配器(部分实现)
类适配器模式结构图
对象适配器模式结构图

适配器模式三个角色

1:Target(目标抽象类):目标抽象类定义客户所需的接口。

2:Adapter(适配器类):它可以调用另一个接口,作为一个转换器,对Adaptee和Target进行适配。它是适配器模式的核心。

3:Adaptee(适配者类):适配者即被适配的角色,它定义了一个已经存在的接口,这个接口需要适配,适配者类包好了客户希望的业务方法。

 

 

例子

公司有一套员工管理系统:

获取员工信息

//员工管理系统  获取员工信息的顶级接口
public interface UserInfo {

    //用户名
    public String getUserName();

    //家庭地址
    public String getHomeAddress();

    //手机号
    public String getMobileNumber();

    //职位级别
    public String getLevel();

}
/**
 * @author: wangmingxin1
 * @create: 2018-11-07 15:56
 **/
public class UserInfoImpl implements UserInfo {

    //仅仅模拟这个操作  实际上是需要从数据库获取这些信息

    @Override
    public String getUserName() {
        return "内部员工姓名:xxx";
    }

    @Override
    public String getHomeAddress() {
        return "内部员工住址:xxx";
    }

    @Override
    public String getMobileNumber() {
        return "内部员工手机:xxx";
    }

    @Override
    public String getLevel() {
        return "内部员工级别:xxx";
    }
}

 

现在问题来了,有段时间公司很忙,非常缺人,到一家外包公司,大量借用在他们公司的员工,等项目完成后,再归还他们的员工

如果我们来一个人在注册到我们自己的系统比较麻烦,到时候还要一个个清除

 

我们直接远程调用他们公司内部登记系统的信息,直接把我们将要借用的人的信息读到我们的员工系统中。

 

外部员工信息的系统和我们的接口不一样,比如是这样的:

//外部系统的用户接口
public interface OuterUser {
    //基本信息
    public Map getUserBaseInfo();
    //工作信息
    public Map getUserJobInfo();
    //家庭信息
    public Map getUserHomeInfo();
}
/**
 * @author: wangmingxin1
 * @create: 2018-11-07 16:11
 **/
public class OuterUserImpl implements OuterUser {
    @Override
    public Map getUserBaseInfo() {
        Map<String,String> baseInfo = new HashMap();

        baseInfo.put("userName", "员工姓名:xxx");
        baseInfo.put("mobileNumber", "员工手机:xxx");

        return baseInfo;
    }

    @Override
    public Map getUserJobInfo() {
        Map<String,String> jobInfo = new HashMap();

        jobInfo.put("level", "员工级别:xxx");

        return jobInfo;
    }

    @Override
    public Map getUserHomeInfo() {

        Map<String,String> homeInfo = new HashMap();

        homeInfo.put("homeAddress", "员工住址:xxx");

        return homeInfo;
    }
}

 

于是我们有了2个不同系统的2个接口

 

那么问题来了,不同的接口,压根实现的方法都不一样,怎么样建立桥梁呢?

于是乎,适配器闪亮登场 ….

 

用适配器包装外部接口,使我们访问外部员工信息就好像访问我们本公司的一样

/**
 * 用适配器包装
 *
 * @author: wangmingxin1
 * @create: 2018-11-07 16:24
 **/
public class OuterUserInfo extends OuterUserImpl implements UserInfo{

    private Map baseInfo = super.getUserBaseInfo();
    private Map jobInfo = super.getUserJobInfo();
    private Map homeInfo = super.getUserHomeInfo();

    @Override
    public String getUserName() {
        String userName = (String) baseInfo.get("userName");
        return userName;
    }

    @Override
    public String getHomeAddress() {
        String homeAddress = (String) homeInfo.get("homeAddress");
        return homeAddress;
    }

    @Override
    public String getMobileNumber() {
        String mobileNumber = (String) baseInfo.get("mobileNumber");
        return mobileNumber;
    }

    @Override
    public String getLevel() {
        String level = (String) jobInfo.get("level");
        return level;
    }
}

 

写主函数测试:

/**
 * @author: wangmingxin1
 * @create: 2018-11-07 16:38
 **/
public class Main {

    public static void main(String[] args){
        //获取内部员工手机号
        UserInfo userInfo = new UserInfoImpl();
        String mobileNumber = userInfo.getMobileNumber();
        System.out.println(mobileNumber);

        //获取外部员工手机号
        userInfo = new OuterUserInfo();
        mobileNumber=userInfo.getMobileNumber();
        System.out.println(mobileNumber);

    }
}

 

运行:

 

上面的一个例子是类适配器

 

结语

  适配器模式原有类对使用者来说是看不到的,在原有类上做一个扩展,对原有类是零修改的,

降低了耦合性,增加了扩展性,以后想怎么适配就怎么适配,有其他的不适配不兼容的情况再写个适配类即可

 

 

 

转载请注明:汪明鑫的个人博客 » 适配器模式

喜欢 (0)

说点什么

您将是第一位评论人!

提醒
avatar
wpDiscuz