浅学设计模式之适配器<Adapter>模式 .

  适配器模式 (adapter pattern)有时候也称包装样式或者包装。将一个的接口转接成用户所期待的。一个适配使得因接口不兼容而不能在一起工作的类工作在一起,做法是将类别自己的接口包裹在一个已存在的类中。

有两类适配器模式:

·对象适配器模式 - 在这种适配器模式中,适配器容纳一个它我包裹的类的实例。在这种情况下,适配器调用被包裹对象的物理实体。

·类适配器模式 - 这种适配器模式下,适配器继承自已实现的类(一般多重继承)。  

    下面我们可以看下类图:

    下面开始一个小例子。假如你朋友从日本给你带来一个日本原装相机,只能使用110V的电压充电,你在国内想使用的话必须使用一个电压转换器把国内的220V电压转换成110V电压。如下图



220V的电压转换成110V给客户。

      开始代码:

客户类:相机

  1. public class Camera {  
  2.     public void charging(String strVoltage) {  
  3.         if (strVoltage.equalsIgnoreCase("110V")) {  
  4.             System.out.println("can charge");  
  5.         } else {  
  6.             System.out.println("the Voltage is not in conformity with the Camera");  
  7.         }  
  8.     }  
  9. }  
public class Camera {
	public void charging(String strVoltage) {
		if (strVoltage.equalsIgnoreCase("110V")) {
			System.out.println("can charge");
		} else {
			System.out.println("the Voltage is not in conformity with the Camera");
		}
	}
}

这里只简单的实现了它的充电功能!

被适配者:220V中国电压

  1. public class ChinaVoltage {  
  2.      String getVoltage(){  
  3.          System.out.println("中国电压是220V");  
  4.          return "220V";  
  5.      };  
  6. }  
public class ChinaVoltage {
	 String getVoltage(){
		 System.out.println("中国电压是220V");
		 return "220V";
	 };
}

适配者:110V

  1. public class JapanVoltage {  
  2.     private String strVoltage = "110V";  
  3.     public String getVoltage() {  
  4.         System.out.println("Japan Voltage is 110V");  
  5.         return strVoltage;  
  6.     }  
  7. }  
public class JapanVoltage {
	private String strVoltage = "110V";
	public String getVoltage() {
		System.out.println("Japan Voltage is 110V");
		return strVoltage;
	}
}

这里没有定义接口,直接使用了实体类!

适配器:

  1. public class VoltageAdapter extends ChinaVoltage{  
  2.     private JapanVoltage japanVoltage;  
  3.       
  4.     public void setJapanVoltage(JapanVoltage japanVoltage) {  
  5.         this.japanVoltage = japanVoltage;  
  6.     }  
  7.   
  8.     @Override  
  9.     public String getVoltage() {  
  10.         // TODO Auto-generated method stub   
  11.         return japanVoltage.getVoltage();  
  12.     }  
  13.       
  14. }  
public class VoltageAdapter extends ChinaVoltage{
	private JapanVoltage japanVoltage;
	
	public void setJapanVoltage(JapanVoltage japanVoltage) {
		this.japanVoltage = japanVoltage;
	}

	@Override
	public String getVoltage() {
		// TODO Auto-generated method stub
		return japanVoltage.getVoltage();
	}
	
}

测试用例:

  1. public static void main(String[] args) {  
  2.         //得到相机   
  3.         Camera camera =new Camera();  
  4.         //得到日本电压和转换器   
  5.         JapanVoltage japanVoltage = new JapanVoltage();  
  6.         VoltageAdapter voltageAdapter = new VoltageAdapter();  
  7.         //转换成日本电压   
  8.         voltageAdapter.setJapanVoltage(japanVoltage);  
  9.         //充电   
  10.         camera.charging(voltageAdapter.getVoltage());  
  11.           
  12.         //直接用中国电压充电   
  13.         camera.charging(new ChinaVoltage().getVoltage());  
  14.     }  
public static void main(String[] args) {
		//得到相机
		Camera camera =new Camera();
		//得到日本电压和转换器
		JapanVoltage japanVoltage = new JapanVoltage();
		VoltageAdapter voltageAdapter = new VoltageAdapter();
		//转换成日本电压
		voltageAdapter.setJapanVoltage(japanVoltage);
		//充电
		camera.charging(voltageAdapter.getVoltage());
		
		//直接用中国电压充电
		camera.charging(new ChinaVoltage().getVoltage());
	}

测试结果:

Japan Voltage is 110V
can charge
中国电压是220V
the Voltage is not in conformity with the Camera


在这里使用的是对象适配器模式,在java中不支持多重继承,所以基本上没办法类继承方式。

但是使用接口加对象的方式试一下吧:

  1. public interface IJapanVoltage {  
  2.     String getJapanVoltage();  
  3. }  
public interface IJapanVoltage {
	String getJapanVoltage();
}

适配器:


  1. public class VoltageAdapter2 extends ChinaVoltage implements IJapanVoltage{  
  2.   
  3.     @Override  
  4.     public String getJapanVoltage() {  
  5.         getVoltage();  
  6.         System.out.println("转换为日本电压为110V");  
  7.         return "110V";  
  8.     }  
  9.   
  10. }  
public class VoltageAdapter2 extends ChinaVoltage implements IJapanVoltage{

	@Override
	public String getJapanVoltage() {
		getVoltage();
		System.out.println("转换为日本电压为110V");
		return "110V";
	}

}



然后测试一下:

  1. public class Test {  
  2.     public static void main(String[] args) {  
  3.         //得到相机   
  4.         Camera camera =new Camera();  
  5.         //得到日本电压和转换器   
  6.         JapanVoltage japanVoltage = new JapanVoltage();  
  7.         VoltageAdapter2 voltageAdapter = new VoltageAdapter2();  
  8.         //充电   
  9.         camera.charging(voltageAdapter.getJapanVoltage());  
  10.           
  11.         //直接用中国电压充电   
  12.         camera.charging(voltageAdapter.getVoltage());  
  13.     }  
  14. }  
public class Test {
	public static void main(String[] args) {
		//得到相机
		Camera camera =new Camera();
		//得到日本电压和转换器
		JapanVoltage japanVoltage = new JapanVoltage();
		VoltageAdapter2 voltageAdapter = new VoltageAdapter2();
		//充电
		camera.charging(voltageAdapter.getJapanVoltage());
		
		//直接用中国电压充电
		camera.charging(voltageAdapter.getVoltage());
	}
}

测试结果:

中国电压是220V
转换为日本电压为110V
can charge
中国电压是220V
the Voltage is not in conformity with the Camera


适用性:

1. 系统需要使用现有的类,而此类的接口不符合系统的需要。

2. 想要建立一个可以重复使用的类,用于与一些彼此之间没有太大关联的一些类,包括一些可能在将来引进的类一起工作。这些源类不一定有很复杂的接口。

3. (对对象适配器而言)在设计里,需要改变多个已有子类的接口,如果使用类的适配器模式,就要针对每一个子类做一个适配器,而这不太实际。

 

效果及优缺点:

对于类适配器:

1. 用一个具体的Adapter类对Adaptee和Taget进行匹配。结果是当我们想要匹配一个类以及所有它的子类时,类Adapter将不能胜任工作。

2. 使得Adapter可以override(重定义) Adaptee的部分行为,因为Adapter是Adaptee的一个子类。

对于对象适配器:

1. 允许一个Adapter与多个Adaptee,即Adaptee本身以及它的所有子类(如果有子类的话)同时工作。Adapter也可以一次给所有的Adaptee添加功能。

2. 使得override(重定义)Adaptee的行为比较困难。如果一定要override Adaptee的方法,就只好先做一个Adaptee的子类以override Adaptee的方法,然后再把这个子类当作真正的Adaptee源进行适配。



最后:本文用图是从Head.First设计模式书上截的图。想学好设计模式,可以好好看看那本书。大笑

周末愉快。。。

如果觉得还可以的话,请帮忙顶一下吧。。。大笑


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值