适配器模式

转载请注明出处!!!http://blog.csdn.net/zhonghuan1992

         所有配套代码均在github上:https://github.com/ZHONGHuanGit/DesignPattern

 




跟着ZHONGHuan学习设计模式

适配器模式






介绍:

         现实中适配器存在很多。就好像变压器,我想读这篇文章的你,很可能是一名学生(起码曾经是吧)。因为现在正好在宿舍写这篇blog。我所在的宿舍是会限电的,电压高了会跳闸,不能使用像电磁炉这样的设备,你懂的,大学里,偶尔宿舍成员在宿舍撮一顿,不能用些煮东西的设备,太没人性了有木有(吐槽下学校的制度),但是,网上有一些称为“变压器”的东西,可以帮你解决这个麻烦。变压器能够转变电压。比如把220v的变成110v;因为有了它,宿舍才能吃上顿大锅饭呐!

         这里变压器的工作就像适配器模式做的工作一样,所以常常称适配器模式为变压器模式。再用head first上的例子,更形象些。

 

面向对象适配器:

         假设已有一个软件系统,你希望它能和一个新的厂商类库搭配使用,但是这个新厂商所涉及出来的接口,不同于旧厂商的接口。

         然后,我们不想改变现有的代码,也不能改变厂商的代码,所以该怎么样才能解决这个问题。可以再写一个类,将新厂商接口转变为你所期望的接口。

        

         这个适配器如同一个中间人,它将现有的系统和厂商类连起来了。

 

从实例中体会适配器模式:

         依旧使用headfirst的例子。有一群鸭子,会呱呱叫,也会飞。给出鸭子的接口:

 

代码:

interface Duck{
         public void quack();//鸭子呱呱叫
         public void fly();//鸭子会飞
}


 

有一种绿头鸭属于鸭子的一种,所以其实现如下:

class MallardDuck implements Duck{
         public void quack(){
                   System.out.println("鸭子呱呱叫");
         }
         public void fly(){
                   System.out.println("我是绿头鸭,我正在飞翔");
         }
}


 

         现在为你介绍一个“街头顽禽”,turkey,火鸡,火鸡不会呱呱叫,只会咯咯叫,灰机也会飞,但是飞的不远。给出火鸡的接口

代码:

interface Turkey{
         public void gobble();
         public void fly();
}


 

有一种野生火鸡,属于火鸡的一种。其实现:

class WildTurkey implements Turkey{
         public void gobble(){
                   System.out.println("火鸡咯咯叫");
         }
         public void fly(){
                   System.out.println("我是火鸡,我正在飞,可是飞不远");
         }
}


 

现在我们缺少鸭子,想要火鸡来充数,接口不同怎么办,火鸡不会呱呱叫,所以,写个适配器解决吧。适配器如下

class TurkeyAdapter implements Duck{
         Turkey turkey;//这个就是要充数的火鸡
         public TurkeyAdapter(Turkey turkey){
                   this.turkey=turkey;//初始化时,告诉适配器,要冒充的火鸡
         }
         public void quack(){
                   turkey.gobble();//火鸡不会呱呱叫,只好用咯咯叫来顶替了
         }
 
         public void fly(){
                   for(int i=0;i<5;i++){
                            turkey.fly();//火鸡飞得不远,所以多飞几次来顶替。
                   }
         }
}


上面的适配器写完了,让我们来测试一下这个适配器。测试代码如下:

public class Main{
         public static void main(String[] args){
                   WildTurkey turkey=new WildTurkey();//先创建一只火鸡
                   Duck turkeyAdapter = new TurkeyAdapter(turkey);//用适配器来包装这个火鸡
                   //这个适配器就好像一个鸭子一样,会quack,会fly
                   turkeyAdapter.quack();
                   turkeyAdapter.fly();
         }
}


 

         现在,已经初步体会适配器的运用了,让我们继续说一下定义。

适配器的定义

         讲一个类的接口,转换成客户期望的另外一个接口。适配器让原本接口不兼容的类可以合作无间。

 

         现在,我们知道,这个模式可以通过创建适配器进行接口转换,让不兼容的接口变得兼容,这可以让客户从实现的接口解耦。如果在一段时间之后,我们想要改变接口,适配器可以将改变的部分封装起来,客户就不必为了应对不同的接口而每次跟着修改。

         看完适配器之后,看下适配器的类图,类图有两种,第一个是对象适配器。第二个是类适配器。想体验他们的差别,请看下面的类图:

 

对象适配器:

 

类适配器:

 

         从上面的类图中,应该可以体会出差别,前面的火鸡冒充鸭子的适配器使用的是对象适配器。其实在java中使用的都是这个,类适配器,是一个多重继承的类图,在其它语言如C++中可以得到实现。

         适配器模式充满着良好的OO设计原则,例如对象适配器使用对象组合,已修改的接口包装被适配者,这种做法还有额外的优点,就是被适配者的任何子类,都可以搭配着是陪着使用。

         也请留意,这个模式是如何把客户和接口绑定起来,而不是和实现绑定起来的。我们可以使用数个适配器,每一个都负责转换不同组的后台类,或者,也可以加上新的实现,只要它们遵守目标接口就可以。

 

客户使用适配器的过程:

         1客户通过目标接口调用适配器的方法对适配器发出请求

         2适配器使用被适配者接口,把强求转换成被适配者的一个或多个调用接口

         3客户接收到调用的结果,但并未察觉这一切是适配器在起转换作用。

 

关于适配器模式的问与答:

:一个适配器只能够封装一个类吗?

         :适配器模式的工作是将一个接口转换成另一个,虽然大多数的适配器模式所采取的的例子都是一个适配器包装一个被适配者,但我们知道这个世界复杂多了,所以可能会遇到一些情况,需要让一个适配器包装多个被适配者。这涉及另一个模式,外观模式。

 

 

 

 

 

  • 8
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值