适配器模式(结构型)

适配器模式(Adapter Pattern)是作为两个不兼容的接口之间的桥梁。这种类型的设计模式属于结构型模式,它结合了两个独立接口的功能。

这种模式涉及到一个单一的类,该类负责加入独立的或不兼容的接口功能。举个真实的例子,读卡器是作为内存卡和笔记本之间的适配器。您将内存卡插入读卡器,再将读卡器插入笔记本,这样就可以通过笔记本来读取内存卡。

介绍

意图:将一个类的接口转换成客户希望的另外一个接口。适配器模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。

主要解决:主要解决在软件系统中,常常要将一些"现存的对象"放到新的环境中,而新环境要求的接口是现对象不能满足的。

何时使用: 1、系统需要使用现有的类,而此类的接口不符合系统的需要。 2、想要建立一个可以重复使用的类,用于与一些彼此之间没有太大关联的一些类,包括一些可能在将来引进的类一起工作,这些源类不一定有一致的接口。 3、通过接口转换,将一个类插入另一个类系中。(比如老虎和飞禽,现在多了一个飞虎,在不增加实体的需求下,增加一个适配器,在里面包容一个虎对象,实现飞的接口。)

如何解决:继承或依赖(推荐)。

关键代码:适配器继承或依赖已有的对象,实现想要的目标接口。

应用实例: 1、美国电器 110V,中国 220V,就要有一个适配器将 110V 转化为 220V。 2、JAVA JDK 1.1 提供了 Enumeration 接口,而在 1.2 中提供了 Iterator 接口,想要使用 1.2 的 JDK,则要将以前系统的 Enumeration 接口转化为 Iterator 接口,这时就需要适配器模式。 3、在 LINUX 上运行 WINDOWS 程序。 4、JAVA 中的 jdbc。

优点: 1、可以让任何两个没有关联的类一起运行。 2、提高了类的复用。 3、增加了类的透明度。 4、灵活性好。

缺点: 1、过多地使用适配器,会让系统非常零乱,不易整体进行把握。比如,明明看到调用的是 A 接口,其实内部被适配成了 B 接口的实现,一个系统如果太多出现这种情况,无异于一场灾难。因此如果不是很有必要,可以不使用适配器,而是直接对系统进行重构。 2.由于 JAVA 至多继承一个类,所以至多只能适配一个适配者类,而且目标类必须是抽象类。


分类

适配器模式有分三类:

  • 1、类适配器模式(class adapter pattern)

  • 2、对象适配器模式(object adapter pattern)

  • 3、缺省适配器模式(default adapter pattern),也叫默认适配器模式、接口适配器模式

 

1、类适配器模式(class adapter pattern)

代码示例

一张图说明需求:

电源适配器

嗯,就是电源适配器了。上面有这样两行:

输入:100-240V ~ 0.5A 50-60HZ

输出:5.2V ==== 2.4A

我们的需求就是将电源输入220V(适配者)转换为5V输出(目标)。

目标角色(PowerTarget.java):

public interface PowerTarget 
{
	public int output5V();
}

适配者角色(PowerAdaptee.java)

public class PowerAdaptee 
{
	private int output =  220;
	public int output220V() 
    {
		System.out.println("电源输出电压:" + output);
		return output;
	}
}

 适配器角色(PowerAdapter.java):

public class PowerAdapter extends PowerAdaptee implements PowerTarget
{
	
	@Override
	public int output5V() 
    {
		int output = output220V();
		System.out.println("电源适配器开始工作,此时输出电压是:" + output);
		output = output/44;
		System.out.println("电源适配器工作完成,此时输出电压是:" + output);
		return output;
	}
	
}

这样就适配了。

类适配器模式测试类(ClassAdapterPatternTest.java):

public class ClassAdapterPatternTest 
{
	
	public static void main(String[] args) 
    {
		PowerTarget target = new PowerAdapter();
		target.output5V();
	}
}

测试结果:
适配器模式示例测试结果

 

2、对象适配器模式(object adapter pattern)

对象适配器模式在运行时实现target(目标)接口。在这种适配器模式中,适配器包装了一个类实例。在这种情况下,适配器调用包装对象实例的方法。

 对象适配器模式(object adapter pattern)结构图:
对象适配器模式结构图

如上图,与类适配器模式不同的是,Adapter只实现了Target的接口,没有继承Adaptee,而是使用聚合的方式引用adaptee。

代码示例

代码示例和类适配器模式只有Adapter类有不同,其他完成一样,连测试结果都是一样。下面只贴上Adapter类。

适配器角色(Adapter.java):

public class PowerAdapter implements PowerTarget
{
	private PowerAdaptee powerAdaptee;

	public PowerAdapter(PowerAdaptee powerAdaptee) 
   {
		super();
		this.powerAdaptee = powerAdaptee;
	}

	@Override
	public int output5V() 
    {
		int output = powerAdaptee.output220V();
		System.out.println("电源适配器开始工作,此时输出电压是:" + output);
		output = output/44;
		System.out.println("电源适配器工作完成,此时输出电压是:" + output);
		return output;
	}
	
}

 实现了PowerTarget(目标角色),在创建对象时引入PowerAdaptee(适配者角色)。

类适配器模式和对象适配器模式的对比

优点

类适配器模式(class adapter pattern):

由于适配器adapter类是适配者adaptee类的子类,因此可以在适配器类中置换一些适配者的方法,即Override(重写),使得适配器的灵活性更强。

对象适配器模式(object adapter pattern):

一个对象适配器可以把多个不同的适配者adaptee适配到一个目标,也就是说,同一个适配器可以将适配者类和它的子类都适配到目标接口。

缺点

类适配器模式:

java8之前:接口没有default方法,就是没有实现了具体逻辑的方法,而且不支持类多继承,所以适配者类只能有一个

java8之后:接口有了default方法,接口中的方法有了实现,因为接口是多继承的,所以适配者可以是多个带有default方法的接口,但是接口是不可以实例化的,实际上没有什么意义。有个解决方法就是,接口里都是default方法,实现接口的类什么也没做,就是提供一个可以实例化的类。这样的化,类适配器模式中适配者adapter类就可以适配多个适配者adaptee类了。这个解决方法只是我理论上论证一下,实际上可行与否,请自行判断验证。

对象适配器模式:

类适配器模式的优点就是对象适配器模式的缺点,不能置换适配者类的方法。如果想修改适配者类的一个或多个方法,就只好先创建一个继承与适配者类的子类,把适配者类的方法置换掉,然后把适配者的子类当做真正的适配者进行适配,实现过程较为复杂。

发布了127 篇原创文章 · 获赞 33 · 访问量 15万+

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 技术黑板 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览