论坛首页 Java企业应用论坛

适配器模式

浏览 15792 次
锁定老帖子 主题:适配器模式
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2011-06-29   最后修改:2011-11-18

Adapter pattern

问题引出:大家生活中可能碰到的一个问题就是你新买的手机自带的耳机是2.5接口的,不幸的是有一天你的耳机坏了,你去市面上根本就找不到2.5的耳机了,基本上是3.5接口了,没办法你只好买了个3.5接口的耳机,老板告诉你:“我给你一个适配器”这不问题就解决了。

问题分析:3.5的接口的耳机在你手机上本来是没法使用的,因为它没有按照2.5接口的设计啊,而现在我又想使用这幅耳机,于是乎有了“适配器(Adapter)”这个一个东西出来了。

Adapter模式的定义:把一个类的接口变换成客户端所期待的另外一种接口,使得原本由于接口不兼容而不能再一起工作的那些类可以一起工作。

适配器模式分类:1.类的适配器模式(采用继承实现)2.对象适配器(采用对象组合方式实现)

类的适配器类图:

 


 

 

 

 

模式的构成:以问题中例子为模型

目标抽象角色(Target):定义客户所期待要使用的接口,我们把手机当做客户端,客户端所需要使用的耳机的接口是2.5的,在这里就可以抽象出来一个2.5接口的设备(并不一定是耳机)。

源角色(Adaptee):需要被适配的接口,在这里指的是我们从市场上买回来的那个3.5接口的耳机。

适配器角色(Adapter)用来把源接口转换成符合要求的目标接口的设备,在这里指的是老板送给我们的那个“转换器”。

客户端(Client)这里指的就是那个给我们带来麻烦的手机喽。

示例代码:

 

//Target

package pattern.adapter;

public interface Target {

    public void provide2_5();

}

//Adaptee

package pattern.adapter;

public class Adaptee {

    public void provide3_5(){

       System.out.println("我是一个3.5的接口哦");

    }

}

//Adapter

package pattern.adapter;

public class Adapter extends Adaptee implements Target {

    @Override

    public void provide2_5() {

       this.provide3_5();

    }

}

//Client

package pattern.adapter;

public class CellPhoneClient {

    public static void main(String[] args) {

       Target target = new Adapter();

       //该手机只支持2.5接口的耳机

       target.provide2_5();

    }

}

 输出结果

我是一个3.5的接口哦

 

从输出结果可以看出只支持2.5接口的手机成功的使用3.5的耳机了。这就是适配器模式的作用。

 

对象的适配器模式:

 

 

 

 

对象的适配器模式的不同之处在于Adapter角色封装了Adaptee角色,而不像类的适配器模式所采取的继承方式。其原理基本上是相似的。

应用适配器模式的场景:

1.系统需要使用现有的类,而现有类不符合当前系统的要求。如问题的提出。

2.系统要建立一个可以重复使用的类,用来与彼此没有太大关联的类或者在将来要引用的类一起工作。在Junit中有使用适配器模式的情景。

TestCaserunBare方法中发现

 

该方法采用了两种模式,模板方法模式(不在本讨论范围)和适配器模式,其中runTest()方法其实 对应的就是我们用户(程序员)所编写的测试方法

 

 

 

runTest方法中通过反射最终调用我们所编写的测试方法。我们可从宏观上来分析改代码,junit作为一个框架,他是没法知道我们要写些什么样的测试方法的,也是就是说他没法在runbare方法中直接调用我们所写的测试方法,他就采用适配器模式这样的一个方式来实现。Junit框架本身没法直接调用客户端所写的测试类,但他可以直接调用他本身拥有的类TestCase,这里的TestCase就相当于Adapter了,自己所写了测试类相当于Adaptee角色。

缺省的适配器模式(Default Adapter)缺省的适配器模式为一个接口提供缺省的实现,子类可以从这个缺省的实现类进行扩展,而不必而原有的接口进行扩展。相信大家在学习Swing时“AWT中事件的处理”有所接触。他的好处在于客户端不需要去实现与他无关的方法,只做他最关心的事。

 

 

 

  • 大小: 36.7 KB
  • 大小: 27.6 KB
  • 大小: 10 KB
  • 大小: 23.1 KB
   发表时间:2011-06-30  
个人理解:适配器就是现有条件不满足,自己diy一个,diy的时候把不满足的利用上

0 请登录后投票
   发表时间:2011-07-02  
个人理解是,已经有个用户,它会使用接口A。你呢已经有个用在其它地方的接口B,这个时候,你想把它给用户使用,这个时候就去适配下。我觉得很重要的一点是,被适配的和适配的都已经被其它用户使用,这个时候才要去适配
0 请登录后投票
   发表时间:2011-07-03   最后修改:2011-07-03

感觉楼主这样写好像有点问题,如果我还要其他型号的接口是不是还得再改写Adapter这个类呢,这不符合OCP原则,也会造成适配器泛滥。为什么不这样写:

 

原始接口

 

package com.lgj.test;

public interface Target {

	public void provide();
}

 

适配器

 

package com.lgj.test;

public class Adapter {

	public void provide(Target target)
	{
		target.provide();
	}
}
 

以下是要的接口,可以任意增加

 

package com.lgj.test;

public class Provide3_5 implements Target{

	public void provide()
	{
		System.out.println("我提供3.5接口");
	}
}

 

 

客户端

 

package com.lgj.test;

public class Client {

	
	public static void main(String[] args)
	{
		Target provide3_5 = new Provide3_5();
	
		Adapter adapter = new Adapter();
		adapter.provide(provide3_5);
	}
}
 

这样写的话,以后无论要怎样的接口,我们都无需更改Adapter,我们只要写个实现自Target的ProvideXX类,然后在客户端装进参数就Ok了,这样适配器就真成通用的了以上是本人愚见。

0 请登录后投票
   发表时间:2011-07-03  
修补匠 写道

感觉楼主这样写好像有点问题,如果我还要其他型号的接口是不是还得再改写Adapter这个类呢,这不符合OCP原则,也会造成适配器泛滥。

 

 

我想你是被我的代码给欺骗了,O(∩_∩)O~,也许我这里只是就事论事,没像你考虑这么周全,谢谢你的提醒。其实这个是符合开闭原则的。稍微修改下代码如下:(这个是基于对象的适配器模式)

//Target   
  
package pattern.adapter;   
  
public interface Target {   
  
    public void provide();   
  
}   
  
//Adaptee   
  
package pattern.adapter;   
  
public class Adaptee {   
  
    public void provide3_5(){   
  
       System.out.println("我是一个3.5的接口哦");   
  
    }   
  
}   
  
//Adapter   
  
package pattern.adapter;   
  
public class Provider2_5 implements Target {   
  
  private Adaptee adaptee;

   public Provider2_5(Adaptee adaptee){
             this.adaptee = adaptee;

   }   


    @Override  
  
    public void provide() {   
  
       adaptee.provide3_5();   
  
    }   
  
}   
  
//Client   
  
package pattern.adapter;   
  
public class CellPhoneClient {   
  
    public static void main(String[] args) {   
  
       Target target = new Provider2_5(new Adaptee());   
  
       //该手机只支持2.5接口的耳机   
  
       target.provide();   
  
    }   
  
}  

 

您说是吗?

0 请登录后投票
   发表时间:2011-07-04  
重构老系统,或者不同系统的整合的时候,适配器会经常排上用场。
0 请登录后投票
   发表时间:2011-11-18  
对于需要可扩展的接口 我还是比较赞成“修补匠”的写法
0 请登录后投票
   发表时间:2011-11-18  
我怎么感觉用自助银行形容比较贴切些
就是用什么卡就连那个银行
亏本的还是ATM
0 请登录后投票
   发表时间:2012-01-04  
实现方式多种多样,相同的目的是在不更改现有系统的基础上,进行修改
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics