Java设计模式笔记(7)适配器模式

适配器模式定义:将一个类的接口变成客户端所期待的另一种接口,从而使原本因接口不匹配而无法在一起工作的两个类能够在一起工作。

适配器模式(Adapter Pattern),适配器模式又叫做变压器模式,也叫做包装模式(Wrapper),但是包装模式却不止一个,装饰模式也是包装模式。

适配器模式包含两种,一种是类适配器,另一种是对象适配器。类适配器是通过类的继承实现的适配,而对象适配器是通过对象间的关联关系,组合关系实现的适配。二者在实际项目中都会经常用到,由于对象适配器是通过类间的关联关系进行耦合的,因此在设计时就可以做到比较灵活,而类适配器就只能通过覆写源角色的方法进行拓展,在实际项目中,对象适配器使用到的场景相对较多。开发中也推荐多使用组合关系,而尽量减少继承关系,这是一种很好的编程习惯,就是使用对象适配器,为什么呢,一直记得在一本书里看过一句话,组合比继承灵活。

适配器模式是一种补救模式,他可以让你从因业务扩展而系统无法迅速适应的苦恼中解脱出来。我们在进行系统开发时,不管之前的可行性分析、需求分析、系统设计处理的多么完美,总会在关键时候、关键场合出现一些“意外”。这些“意外”,该来的还是要来,躲是躲不过的,而这时就是我们的适配器模式的用武之地。适配器模式最好在设计阶段不要考虑它,它不是为了解决还处在开发阶段的问题,而是解决正在服役的项目问题,没有一个系统分析师会再做详细设计时考虑使用适配器模式。

适配器模式的角色说明:

  • Target目标角色:该角色定义把其他类转换为何种接口,也就是我们的期望接口。
  • Adaptee源角色:你想把“谁”转换成目标角色,这个“谁”就是源角色,它是已经存在的、运行良好的类或对象。
  • Adapter适配器角色:适配器模式的核心角色,其他两个角色都是已经存在的角色,而适配器角色是需要新建立的,他的职责非常简单:把源角色转换为目标角色。

适配器模式优点:

  1. 适配器模式可以让两个没有任何关系的类在一起运行,只要适配器这个角色能够搞定他们就成。
  2. 增加了类的透明性。我们访问的是目标角色,但是实现却在源角色里。
  3. 提高了类的复用度。源角色在原有系统中还是可以正常使用的。
  4. 灵活性非常好。不想要适配器时,删掉这个适配器就好了,其他代码不用改。
1. 模版代码
目标角色。目标角色是一个已经在正式运行的角色,不可能修改角色中的方法,能做的只是如何去实现接口中的方法,而且通常情况下,目标角色是一个接口或者抽象类。
public interface Target {
	
	//目标角色有自己的方法
	public void request();
}

目标角色的实现类,一个正在服役的目标角色。
public class ConcreteTarget implements Target {

	public void request() {
		System.out.println("I have nothing to do. if you need any help,pls call me!");	}

}

源角色。源角色也是已经在服役状态。
public class Adaptee {
	
	//原有的业务逻辑
	public void doSomething(){
		System.out.println("I'm kind of busy,leave me alone,pls!");
	}
}

适配器角色,对象适配器和类适配器。
对象适配器代码:
public class Adapter implements Target {

	private Adaptee adaptee;
	
	public Adapter() {
		adaptee = new Adaptee();
	}

	public void request() {
		adaptee.doSomething();
	}

}

类适配器代码:
public class Adapter extends Adaptee implements Target {

	public void request() {
		super.doSomething();
	}

}

场景类:
public class Client {
	
	public static void main(String[] args) {
		//原有的业务逻辑
		Target target = new ConcreteTarget();
		target.request();
		
		//现在增加了适配器角色后的业务逻辑
		Target target2 = new Adapter();
		target2.request();
	}
}

2. 手机电源适配器例子,家用电源是220V的,但是,对于手机来说,根本大不了这么多,所以,在这种情况下,需要电源适配器来为我们提供适合手机的电压。
public class Client {
	public static void main(String[] args) {
		Target mobliePower = new MobilePowerAdapter();
		int power = mobliePower.getPower10V();
		System.out.println("the mobile power is " + power + "V");
	}
}

interface Target {
	int getPower10V();
}

class Power {
	public int getPower220V() {
		return 220; 
	}
}

class MobilePowerAdapter implements Target {

	private Power mPower;
	
	public MobilePowerAdapter() {
		mPower = new Power();
	}

	@Override
	public int getPower10V() {
		int power = mPower.getPower220V();
		power = 10;
		return power;
	}
	
}

3. 最后一个例子:
public interface IOuterUserBaseInfo {
	//基本信息,比如名称,性别,手机号码了等
	public Map getUserBaseInfo();
}

public interface IOuterUserHomeInfo {
	//用户的家庭信息
	public Map getUserHomeInfo();
}

public interface IOuterUserOfficeInfo {
	//工作区域信息
	public Map getUserOfficeInfo();
}

public class OuterUserBaseInfo implements IOuterUserBaseInfo {

	/* 
	 * 用户的基本信息
	 */
	public Map getUserBaseInfo() {
		HashMap baseInfoMap = new HashMap();
		
		baseInfoMap.put("userName", "这个员工叫混世魔王....");
		baseInfoMap.put("mobileNumber", "这个员工电话是....");
		
		return baseInfoMap;
	}

}

public class OuterUserHomeInfo implements IOuterUserHomeInfo {

	/* 
	 * 员工的家庭信息
	 */
	public Map getUserHomeInfo() {
		HashMap homeInfo = new HashMap();
		
		homeInfo.put("homeTelNumbner", "员工的家庭电话是....");
		homeInfo.put("homeAddress", "员工的家庭地址是....");
		
		return homeInfo;
	}
}

public class OuterUserOfficeInfo implements IOuterUserOfficeInfo {

	/* 
	 * 员工的工作信息,比如职位了等
	 */
	public Map getUserOfficeInfo() {
		HashMap officeInfo = new HashMap();
		
		officeInfo.put("jobPosition","这个人的职位是BOSS...");
		officeInfo.put("officeTelNumber", "员工的办公电话是....");
		
		return officeInfo;
	}

}

//用户信息对象
public interface IUserInfo {
	
	//获得用户姓名
	public String getUserName();
	
	//获得家庭地址
	public String getHomeAddress();
	
	//手机号码,这个太重要,手机泛滥呀
	public String getMobileNumber();
	
	//办公电话,一般式座机
	public String getOfficeTelNumber();
	
	//这个人的职位是啥
	public String getJobPosition();
	
	//获得家庭电话,这个有点缺德,我是不喜欢打家庭电话讨论工作
	public String getHomeTelNumber();
}

public class UserInfo implements IUserInfo {

	/* 
	 * 获得家庭地址,下属送礼也可以找到地方
	 */
	public String getHomeAddress() {
		System.out.println("这里是员工的家庭地址....");
		return null;
	}

	/* 
	 * 获得家庭电话号码
	 */
	public String getHomeTelNumber() {
		System.out.println("员工的家庭电话是....");
		return null;
	}

	/* 
	 * 员工的职位,是部门经理还是小兵
	 */
	public String getJobPosition() {
		System.out.println("这个人的职位是BOSS....");
		return null;
	}

	/* 
	 * 手机号码
	 */
	public String getMobileNumber() {
		System.out.println("这个人的手机号码是0000....");
		return null;
	}

	/* 
	 * 办公室电话,烦躁的时候最好“不小心”把电话线踢掉,我经常这么干,对己对人都有好处
	 */
	public String getOfficeTelNumber() {
		System.out.println("办公室电话是....");
		return null;
	}

	/* 
	 * 姓名了,这个老重要了
	 */
	public String getUserName() {
		System.out.println("姓名叫做...");
		return null;
	}

}

//把OuterUser包装成UserInfo
@SuppressWarnings("all")
public class OuterUserInfo implements IUserInfo {
	//源目标对象
	private IOuterUserBaseInfo baseInfo = null;  //员工的基本信息
	private IOuterUserHomeInfo homeInfo = null; //员工的家庭 信息
	private IOuterUserOfficeInfo officeInfo = null; //工作信息
	
	//数据处理
	private Map baseMap = null;
	private Map homeMap = null;
	private Map officeMap = null;
	
	//构造函数传递对象
	public OuterUserInfo(IOuterUserBaseInfo _baseInfo,IOuterUserHomeInfo _homeInfo,IOuterUserOfficeInfo _officeInfo){
		this.baseInfo = _baseInfo;
		this.homeInfo = _homeInfo;
		this.officeInfo = _officeInfo;
		
		//数据处理
		this.baseMap = this.baseInfo.getUserBaseInfo();
		this.homeMap = this.homeInfo.getUserHomeInfo();
		this.officeMap = this.officeInfo.getUserOfficeInfo();
	}
	
	 //家庭地址
	public String getHomeAddress() {
		String homeAddress = (String)this.homeMap.get("homeAddress");
		System.out.println(homeAddress);
		return homeAddress;
	}

	 //家庭电话号码
	public String getHomeTelNumber() {
		String homeTelNumber = (String)this.homeMap.get("homeTelNumber");
		System.out.println(homeTelNumber);
		return homeTelNumber;
	}

	 //职位信息
	public String getJobPosition() {
		String jobPosition = (String)this.officeMap.get("jobPosition");
		System.out.println(jobPosition);
		return jobPosition;
	}

	 //手机号码
	public String getMobileNumber() {
		String mobileNumber = (String)this.baseMap.get("mobileNumber");
		System.out.println(mobileNumber);
		return mobileNumber;
	}

	 //办公电话
	public String getOfficeTelNumber() {
		String officeTelNumber = (String)this.officeMap.get("officeTelNumber");
		System.out.println(officeTelNumber);
		return officeTelNumber;
	}
	
	// 员工的名称
	public String getUserName() {
		String userName = (String)this.baseMap.get("userName");
		System.out.println(userName);
		return userName;
	}

}

//这就是我们具体的应用了,比如老板要查所有的20-30的女性信息
public class Client {


	public static void main(String[] args) {
	
		//外系统的人员信息
		IOuterUserBaseInfo baseInfo = new OuterUserBaseInfo();
		IOuterUserHomeInfo homeInfo = new OuterUserHomeInfo();
		IOuterUserOfficeInfo officeInfo = new OuterUserOfficeInfo();
		//传递三个对象
		IUserInfo youngGirl = new OuterUserInfo(baseInfo,homeInfo,officeInfo); 
		//从数据库中查到101个
		for(int i=0;i<101;i++){
			youngGirl.getMobileNumber();
		}
		
		
	}

}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值