理解适配器设计模式需要从生活中的场景进行联系,在生活当中有那些东西能够称为适配器呢?从字面上理解,“适配”的意思就是让一个东西和另一个东西配对,能够让他们一起工作,比如大家用的笔记本电脑就需要用到电源适配器,转换插口和电流到笔记本上给笔记本电脑进行供电。再比如在国内所有的电器插座都是两口或三口的国内标准插座,但如果到中国大陆以外的地区旅行,想要使用电源给电子产品供电,就需要转换插口了。比如王老师到了香港,看到的电源插座是这样的:
很明显,从国内带去的手机就无法充电了。
那么这个问题怎么解决呢?
经过查找资料,王老师找到了一种产品,它就是长成这个样子的东东,叫“电源适器”。
用法相信大家一看就清楚了。
有个它,妈妈再也不用担心我担心我没有电了。
“哦!我知道了,这不是个转换口吗?”是的,其实跟读卡器的概念是一样的,就是将原本不能用的接口经过适配器转换成能用的接口。
概念:
适配器模式(Adapter):将一个类的接口,转换成客户希望的另一个接口。适配器模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。
“还是没读懂!”不要紧,下面简单易懂的案例+代码,让你明白什么是适配器模式。
接下来我们就以电源这个案例来介绍适配器模式:
这里有两个不兼容的接口,电源A接口和电源B接口,并且有各自相应的实现方法。代码如下:
那么两个接口应该有各自的实现类,代码如下:
接下来就应该是客户端来调用了,先定义电源A开始工作方法:
那么想要调用start方法就需要传入PowerA的实现类对象了。
所以这里我们创建一个PowerAImpl对象,并且调用start方法。
编译后运行的结果是这样滴:
我们这里已经写好了,如果这时我们想传PowerB接口到start方法可以吗?怎么办呢?
那么此时我们有两种办法来实现,第一种:
再添加一个startB方法,但这不是一个好的解决方案,因为在startA中调用insert方法的前后我们可能存在一些逻辑以及业务,同样的在startB中调用connect方法的前后可能存在这些相同的逻辑及业务,就只有connect方法调用这一句不同,那么重写一份就是多余的了,代码重复了。不太符合我们面向对象的编程思想,怎么办呢?往下看。
接下来看第二种解决方案:我们还是想用一个start方法解决这个问题,到这里会有人想到直接把start方法改成适应两个接口的,王老师在此处需要先给大家说明一个问题了,面向对象的编程原则中有一点非常重要的是“对修改关闭,对扩展开放”,如果我们的程序已经上线运行,当时并没有考虑要传PowerB接口进来,只传PowerA接口就好了,但现在业务修改要求也可以传PowerB接口,那么修改方法将对其他已写好的程序造成怎样的影响也是未知的,可能其他小伙伴调用了你的start方法就会出问题了,也就是说调用了你的start方法的代码都会有连锁反应了。OK!看下面!
我们需要实现这样的东东。
很显然这样的代码编译是不会通过的,因为目前PowerA和PowerB本来就是两个不同的接口,相当于一个三口的插座和一个两口的根本插不进入是一样的。
要想实现转换,现在需要适配器啦!我们需要把PowerB转换成PowerA传进来,那么我们就给PowerA做一个适配器。
1、首先要适配的是PowerA,所以实现PowerA接口,那么PowerAAdapter就可以作为PowerA的实现类传进start方法了。
2、我们是要用这个适配器将PowerB转成PowerA,那么就需要和PowerB取得联系,所以定义一个PowerB作为属性,并通过构造方法进行初始化操作。
3、实现了PowerA接口需要重写其方法,那么在重写的insert方法中调用PowerB的connect方法,适配器就写好了。
现在来测试一下:
编译之后运行结果是这样滴:
结果说明PowerB接口的实现类开始工作了,但传参数的时候是通过PowerA接口的形式传进来进行工作的。这就是神奇的适配器模式啦!
按照步骤敲一敲代码!更有助于理解!