设计模式之适配器模式

1 概述

  适配器模式(Adapter),说白了就是为了挂羊头卖狗肉而专门设计的模式。也就是把一个类的接口变换成客户端所期待的另一种接口。

  适配器模式通过定义一个新的接口(对要实现的功能加以抽象),和一个实现该接口的Adapter(适配器)类来透明地调用外部组件。这样替换外部组件时,最多只要修改几个Adapter类就可以了,其他源代码都不会受到影响。

     还是以手机为例子,每一种机型都自带有从电器,有一天自带充电器坏了,而且市场没有这类型充电器可买了,怎么办?万能充电器就可以解决,这个万能充电器就是适配器。

     适配器模式有两种形式,一种是类的适配,另一种自然就是对象的适配。

1.1 类的适配

    这种适配方式,由以下几个角色组成:

(1)目标(Target)角色:这就是所期待得到的接口。注意:由于这里讨论的是类适配器模式,因此目标不可以是类。

(2)源(Adapee)角色:现在需要适配的接口。

(3)适配器(Adaper)角色:适配器类是本模式的核心。适配器把源接口转换成目标接口。显然,这一角色不可以是接口,而必须是具体类。

1.2 对象的适配

  对象的适配依赖于对象的组合,而不是类适配中的继承。

     直接上例子来说明更容易理解。

2 示例

    首先来一个IPhone的充电器类(Adaptee角色):

 1 package org.scott.adapter;
 2 /** 
 3  * @author Scott
 4  * @date 2013-11-23 
 5  * @description
 6  */
 7 public class IPhoneCharger {
 8     public void applePhoneCharge(){
 9         System.out.println("The iPhone is charging ...");
10     }
11 }

 

现在,要对这个特殊的充电器进行适配,上个适配的接口(Target角色)

1 package org.scott.adapter;
2 /** 
3  * @author Scott
4  * @date 2013-11-23 
5  * @description
6  */
7 public interface ChargeAdapter {
8     public void phoneCharge();
9 }

 

因为适配有两种,所以先进行类的适配示例,创建类的适配器

 1 package org.scott.adapterclass;
 2 
 3 import org.scott.adapter.ChargeAdapter;
 4 import org.scott.adapter.IPhoneCharger;
 5 
 6 /** 
 7  * @author Scott
 8  * @date 2013-11-23 
 9  * @description
10  */
11 public class UniversalCharger extends IPhoneCharger implements ChargeAdapter{
12 
13     @Override
14     public void phoneCharge() {
15         System.out.println("The phone is charging, but which kind of phone it is, who cares ...");
16         
17         //iphone charging
18         super.applePhoneCharge();
19     }
20     
21 }

这就是万能充电器了,我们让它来充个电,测试类准备:

 1 package org.scott.adapterclass;
 2 
 3 import org.scott.adapter.ChargeAdapter;
 4 
 5 /** 
 6  * @author Scott
 7  * @date 2013-11-23 
 8  * @description
 9  */
10 public class AdapterClassTest {
11 
12     public static void main(String[] args) {
13         ChargeAdapter charger = new UniversalCharger();
14         charger.phoneCharge();
15     }
16 
17 }

 

充电结果:

The phone is charging, but which kind of phone it is, who cares ...
The iPhone is charging ...

 

ok,以上是类的适配,我们还有种对象的适配方式,创建对象的适配器

 1 package org.scott.adapterobject;
 2 
 3 import org.scott.adapter.ChargeAdapter;
 4 import org.scott.adapter.IPhoneCharger;
 5 
 6 /** 
 7  * @author Scott
 8  * @date 2013-11-23 
 9  * @description
10  */
11 public class UniversalCharger implements ChargeAdapter{
12     IPhoneCharger iphoneCharger;
13     
14     public UniversalCharger(IPhoneCharger iphoneCharger){
15         this.iphoneCharger = iphoneCharger;
16     }
17     
18     @Override
19     public void phoneCharge() {
20         System.out.println("The phone is charging, but which kind of phone it is, who cares ...");
21         iphoneCharger.applePhoneCharge();    
22     }
23 
24 
25 }

 

新一代对象适配器创建完毕,测一把:

 1 package org.scott.adapterobject;
 2 
 3 import org.scott.adapter.ChargeAdapter;
 4 import org.scott.adapter.IPhoneCharger;
 5 
 6 /** 
 7  * @author Scott
 8  * @date 2013-11-23 
 9  * @description
10  */
11 public class AdapterObjectTest {
12 
13     public static void main(String[] args) {
14         IPhoneCharger iphoneCharger = new IPhoneCharger();
15         ChargeAdapter charger = new UniversalCharger(iphoneCharger);
16         charger.phoneCharge();
17     }
18 
19 }

 

运行结果:

The phone is charging, but which kind of phone it is, who cares ...
The iPhone is charging ...

 

ok,目的也达到了。

  小节一下。

(1)类的适配器模式:当希望将一个类转换成满足另一个新接口的类时,可以使用类的适配器模式,创建一个新类,继承原有的类,实现新的接口即可。

(2)对象的适配器模式:当希望将一个对象转换成满足另一个新接口的对象时,可以创建一个包装类,持有原类的一个实例,在包装类的方法中,调用实例的方法就行。

  自然,最后还是要来个UML图(源自网络):

类适配:

对象适配:

 

posted @ 2013-11-23 23:03  Scott007  阅读(4337)  评论(0编辑  收藏  举报