java-设计模式(结构型)-【适配器模式】

1.适配器(Adapter Mode)

    定义:将两个不兼容类纠合在一起使用,属于结构型模式,需要有Adaptee(被适配者)和Adapter(适配器)两个身份

             目的是消除由于接口不匹配所造成的类的兼容性问题。

             我们经常碰到需要将两个没有关系的类组合在一起使用,第一种方法是,修改各自的接口,但是违背了开闭原则

             第二种方法是,使用Adapter,在两种接口之间创建一个混合接口(混血儿)。

    分类:类的适配器模式、对象的适配器模式、接口的适配器模式

    三个角色:

  • 目标角色(Traget:interface):期待得到的接口
  • 源(Adapee)角色:现在需要适配的接口
  • 适配器(Adapter:class)角色:必须是具体类

    1.1 类的适配器模式:继承的方式适配

     1.1.1 图解

       

     1.1.2  三个角色

  //待适配的源
public class Source {
    //方法一:
	public void method1()
	{
		System.out.println("source:method1方法");
	}
}
  //需要实现的接口
interface Targetable
{     
	void method1();
    //方法二
	void method2();
}
 //以类继承的方式进行适配
class Adapter extends Source implements Targetable
{
    //继承了方法一
    //重写方法二:
	@Override
	public void method2() {
		// TODO Auto-generated method stub
		System.out.println("Targetable:method2方法");
	}
}

     1.1.3  测试

public class Test {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
       //使用Target接口里定义的方法,不需要"Adapter ad"
	   Targetable ad=new Adapter();
	   System.out.println("adapter-----");
	   ad.method1();
	   ad.method2();
	   Targetable wp=new Wrapper(new Source());
	   System.out.println("wrapper-----");
	   wp.method1();
	   wp.method2();
	}
}

     1.1.4 运行结果  

adapter-----
source:method1方法
Targetable:method2方法
wrapper-----
source:method1方法
Targetable:method2方法

  1.2 对象适配器:组合的方式适配

    1.2.1 图解

      

    1.2.2 代码

public class Source {

	public void method1()
	{
		System.out.println("source:method1方法");
	}
}
interface Targetable
{
	void method1();
	void method2();
}

class Wrapper implements Targetable
{ 
    //组合的方式适配
    private Source s=null;
    public Wrapper(Source s)
    {
    	this.s=s;
    }
	@Override
	public void method1() {
		// TODO Auto-generated method stub
		s.method1();
	}

	@Override
	public void method2() {
		// TODO Auto-generated method stub
		System.out.println("Targetable:method2方法");
	}
	
}

1.3 两者方式的对比

  • 类适配器使用对象继承的方式,是静态的定义方式;而对象适配器使用对象组合的方式,是动态组合的方式。
  • 对象适配器:一个适配器可以把多种不同的源(以多态形式:将子类传入)适配到同一个目标。换言之,同一个适配器可以把源类和它的子类都适配到目标接口。
  •                  因为对象适配器采用的是对象组合的关系,只要对象类型正确,是不是子类都无所谓。
  • 类适配器:由于适配器直接继承了Adaptee,使得适配器不能和Adaptee的子类一起工作,因为继承是静态的关系,
  •               当适配器继承了Adaptee后,就不可能再去处理  Adaptee的子类了。
  • 类适配器:适配器可以重定义Adaptee的部分行为,相当于子类覆盖父类的部分实现方法。
  • 对象适配器:重定义Adaptee的行为比较困难,这种情况下,可以通过定义Adaptee的子类来实现重定义,然后让适配器组合子类。
  •                  虽然重定义Adaptee的行为比较困难,但是想要增加一些新的行为则方便的很,而且新增加的行为可同时适用于所有的源。

     建议尽量使用对象适配器的实现方式,多用合成/聚合、少用继承。当然,具体问题具体分析,根据需要来选用实现方式,最适合的才是最好的。

1.4 接口适配器:对接口的部分方法用抽象类抽出来实现使用

       

     1.4.1 代码

//接口:待适配中
interface Targetable
{
	void method1();
	void method2();
}
//抽象类:中间层,让子接口无需实现父接口的所有未实现方法,有选择的实现自己要实现的方法
 abstract class Wrapper2 implements Targetable
{
		public void method1(){}
		public void method2(){}
}
//只实现方法1
class SourceSub1 extends Wrapper2
{
	public void method1()
	{
		System.out.println("SourceSub1:method1");
	}
}
//只实现方法2
class SourceSub2 extends Wrapper2
{
	public void method2()
	{
		System.out.println("SourceSub2:method2");
	}
}

  1.4.2 测试

public class Test {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
       //使用Target接口里定义的方法,不需要"Adapter ad"
	   Targetable s1=new SourceSub1();
	   Targetable s2=new SourceSub2();
	   //S1:只实现方法1
	   s1.method1();
	   s1.method2();
	   //S2:只实现方法2
	   s2.method1();
	   s2.method2();
     }
}

  1.4.3 运行结果

SourceSub1:method1
SourceSub2:method2

1.5 适配器的优点

  •  更好的复用性

  系统需要使用现有的类,而此类的接口不符合系统的需要。那么通过适配器模式就可以让这些功能得到更好的复用。

  •  更好的扩展性

  在实现适配器功能的时候,可以调用自己开发的功能,从而自然地扩展系统的功能。

 

posted @ 2015-04-14 18:25  beyondbycyx  阅读(148)  评论(0编辑  收藏  举报