专栏首页Spring Cloud设计原理Java 设计模式 适配器模式

Java 设计模式 适配器模式

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://louluan.blog.csdn.net/article/details/18404759

当现有的某个类的接口不能满足客户所需要的接口,需要将这个类的接口转换为客户想要的接口,可以使用适配器模式。这相当于给接口做了一个适配,使这个接口可以在现有的模块内可以使用。

       举一个简单的例子,我们国家家用电网提供的是220V交流电,对于台式机而言,主板需要12V直流电,当然不能直接拿交流电来使用啦。所以主机都有一个电源适配器,将220V 交流电 转换成 12V直流电。这个电源适配器就是从中间起到了一个转换的作用。

看一下类图:

package com.lou.adapter.instance;

public interface AbstractComputerPower {

	/*
	 * 直流电电源 提供直流电
	 */
	public String provideDirectCurrent();
}
package com.lou.adapter.instance;

public interface AbstractNationalPower {

	/*
	 * 国家电网提供交流电
	 */
	public String provideAlternatableCurrent();
}
package com.lou.adapter.instance;

public class ComputerPowerAdapter implements AbstractComputerPower {

	private AbstractNationalPower power = new ChinesePower();
	@Override
	public String provideDirectCurrent() {
		
		String nationalPower = power.provideAlternatableCurrent();
		return transfer(nationalPower);
	}

	private String transfer(String nationalPower)
	{
		System.out.println( "对交流电整流,变压,输出直流电");
		return "12V 直流电";
	}
}
package com.lou.adapter.instance;

public class Client {

	public static void main(String[] args) {
		AbstractComputerPower  computerPower = new ComputerPowerAdapter();
		computerPower.provideDirectCurrent();
	}
}
package com.lou.adapter.instance;

public class ChinesePower implements AbstractNationalPower {

	@Override
	public String provideAlternatableCurrent() {
		return "220V 交流电。";
	}
}

综上,适配器模式是指:

         将一个类的接口转换成客户希望的另外一个接口。Adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。——Gang of Four

适配器的通用模型为:

 适配器模式最后真正完成业务的还是靠原来的接口,adapter从中间起到了转换,代理的作用。

再举一个更实际的例子:

在 项目中会涉及到查询用户信息的相关操作,在当前系统内,既有的底层提供的用户信息接口如下:

package com.lou.patterns.adapter;

public interface UserInfo {

	public String getUserName();
	
	public String getUserId();
	
	public Integer getUserAge();
	
	public String getUserProvince();
	
	public String getUserCity();
	
	public String getUserStreet();
	
}

当前系统内,用户查询接口 可以查询 用户名,用户id,年龄 ,用户所在的省份,所在的城市,所在的街道。

但是现在系统的另外一个模块定义的用户查询 接口如下:

package com.lou.patterns.adapter;

public interface UserInformation {

	public String getUserName();
	
	public String getUserId();
	
	public Integer getUserAge();
         //UserAddredss = province + city + street;	
         public String getUserAddress();
    
}

即:这个模块定义的用户查询接口应该为 查询用户名,用户id,用户年龄,用户的地址 现在就会存在问题:因为这个模块定义的接口和底层定义的接口不兼容,无法将底层的UserInfo 实现类直接拿来使用,现在要在这两个接口之间架起一道桥梁,使我们可以是两个模块兼容起来,所以,我们构造一个适配器,这个适配器要能完成 UserInformation 定义的功能:

package com.lou.patterns.adapter;

public class UserInfoAdapter implements UserInformation{

	private UserInfo userInfo;

	@Override
	public String getUserName() {
		return userInfo.getUserName();
	}

	@Override
	public String getUserId() {
		return userInfo.getUserId();
	}

	@Override
	public Integer getUserAge() {
		return userInfo.getUserAge();
	}

	@Override
	public String getUserAddress() {
		return userInfo.getUserProvince()+" " + userInfo.getUserCity()+ " " +userInfo.getUserStreet();
	}
}
package com.lou.patterns.adapter;

public class UserInfoImpl implements UserInfo{

	UserBean userBean = new UserBean();
	@Override
	public String getUserName() {
		return userBean.getName();
	}

	@Override
	public String getUserId() {
		return userBean.getId();
	}

	@Override
	public Integer getUserAge() {
		return userBean.getAge();
	}

	@Override
	public String getUserProvince() {
		return userBean.getProvince();
	}

	@Override
	public String getUserCity() {
		return userBean.getCity();
	}

	@Override
	public String getUserStreet() {
		return userBean.getStreet();
	}

}
package com.lou.patterns.adapter;

public class UserBean {

	private String name;
	private String id;
	private Integer age;
	private String province;
	private String city;
	private String street;
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getId() {
		return id;
	}
	public void setId(String id) {
		this.id = id;
	}
	public Integer getAge() {
		return age;
	}
	public void setAge(Integer age) {
		this.age = age;
	}
	public String getProvince() {
		return province;
	}
	public void setProvince(String province) {
		this.province = province;
	}
	public String getCity() {
		return city;
	}
	public void setCity(String city) {
		this.city = city;
	}
	public String getStreet() {
		return street;
	}
	public void setStreet(String street) {
		this.street = street;
	}
}

这样,两个模块就可以兼容起来使用了。

总结:

适配器模式在于,adaptee在系统中的不可代替性,一般为模块的底层或者是基础部分,当遇到不兼容的情况时,不方便或者对于当前系统稳定性和拓展性的考虑,应当遵循 “对修改关闭,对拓展开放”的原则,使用适配器模式可以很好地满足这一点。

这里的适配器模式,有一定程度的代理模式的意味在里面,真正业务的实现偏重在adaptee实现,adapter再对其进行转换,满足另外一个模块的要求。

个人观点,欢迎拍砖。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • Java 反射机制

    版权声明:本文为博主原创文章,未经博主允许不得转载。 https://louluan.blog.c...

    亦山
  • Java 设计模式 代理模式

    版权声明:本文为博主原创文章,未经博主允许不得转载。 https://louluan.blog.c...

    亦山
  • Java 设计模式 工厂模式

    版权声明:本文为博主原创文章,未经博主允许不得转载。 https://louluan.blog.c...

    亦山
  • Spring boot整合shiro权限管理

    二十三年蝉
  • 资源池模式和单例模式实现的自定义数据库连接池java实现版

    在企业级开发中,我们往往不会直接使用原生的JDBC操作来实现与数据库得连接。因为数据库的连接是一个很宝贵的资源且耗时,我们往往会在内存中引入一个资源池来统一管理...

    Theone67
  • SpringBoot邂逅Shiro-前后端分离时的配置

    本篇仅是记录集成的基础过程,至于shiro框架的基础概念和使用细节,可以自行查阅相关资料,本文不做讨论。

    汐楓
  • 设计模式(一) 支付策略模式

    公司最近在做直播功能,底层原来有一套直播API,现在新增一套网宿直播API。 考虑以后的扩展性,需要将两套API进行统一管理。现在以网上的支付方式演示我对策略模...

    用户1518699
  • 设计模式(一) 支付策略模式

    公司最近在做直播功能,底层原来有一套直播API,现在新增一套网宿直播API。 考虑以后的扩展性,需要将两套API进行统一管理。现在以网上的支付方式演示我对策略模...

    用户1518699
  • Java基础-17(01)总结,登录注册案例,Set集合,HashSet

    1:登录注册案例(理解) 需求:用户登录注册案例。 按照如下的操作,可以让我们更符号面向对象思想 A:有哪些类呢? B:每个类有哪些东西呢? C:类与类之...

    奋斗蒙
  • Java设计模式学习记录-建造者模式

    今天周末,有小雨,正好也不用出门了,那就在家学习吧,经过了两周的面试,拿到了几个offer,但是都不是自己很想去的那种,要么就是几个人的初创小公司,要么就是开发...

    纪莫

扫码关注云+社区

领取腾讯云代金券