设计模式复习之适配器模式

一、概念

适配器模式是一种结构型模式,所谓结构性模式(Structural Pattern):

描述如何将类或者对象结合在一起,以此来形成更大的结构。

结构型模式可以分为类结构型和对象结构型,其中,类结构型模式关心类层次的组合,一般只存在继承关系和实现关系;而对象结构型关心类与对象的组合,通过关联关系使得在一个类中定义另外一个类的实例对象。根据尽量用组合而不用继承的原则,大部分结构型模式都是对象结构型。

适配器模式:

将一个接口转换成客户希望的另一个接口,适配器模式使接口不兼容的那些类可以一起工作,其别名为包装器(Wrapper)。适配器模式既可以作为类结构型模式,也可以作为对象结构型模式。

由此可见,适配器模式的主要功能在于“兼容”,在适配器模式中定义一个包装类(也就是适配器,Adapter),用来包装不被客户端兼容的对象,这个对象就是适配者(Adaptee),但这个过程对客户端是透明的,客户端并不知道Adapter内部调用了Adaptee的方法。

二、类图

类适配器

ClassAdapter

对象适配器

ObjectAdapter

三、实例代码

以下是类结构型适配器的简单代码:

package adapter;

public class TestClassAdapter {

    /**
     * @param args
     */
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        testRequeset();
    }
    
    public static void testRequeset() {
        
        System.out.println("TestClassAdapter.request");
        Target target = new Adapter();
        target.request();
    }
}

interface Target {
    void request();
}

class Adaptee {
    public void SpecificRequest() {
        System.out.println("Adaptee.SpecificRequest");
    }
}

class Adapter extends Adaptee implements Target {

    @Override
    public void request() {
        // TODO Auto-generated method stub
        System.out.println("Adapter.request");
        SpecificRequest();
    }
}

四、JDK和适配器

       在jdk中,有很多代码都是用到各个类型的设计模式,比如InputStreamReader和OutputStreamWrite就用到了适配器模式。拿InputStreamReader举例,使用的是对象适配器,它继承自Reader(就是Target),并在这个对象中持有StreamDecoder(Adaptee)对象:

public class InputStreamReader extends Reader
private final StreamDecoder sd;

构造InputStreamReader时会初始化这个空白final对象,拿其中之一构造函数来看:

public InputStreamReader(InputStream in) {
    super(in);
        try {
        sd = StreamDecoder.forInputStreamReader(in, this, (String)null); // ## check lock object
        } catch (UnsupportedEncodingException e) {
        // The default encoding should always be available
        throw new Error(e);
    }
    }

当Client调用read()方法时,适配器InputStreamReader会将请求适配给适配者,既调用StreamDecoder对象的read方法:

public int read() throws IOException {
        return sd.read();
    }

    public int read(char cbuf[], int offset, int length) throws IOException {
    return sd.read(cbuf, offset, length);
    }

这样,在Client不知情的情况下,达到了接口兼容的效果。

五、总结

1、优缺点

1)将目标类和适配者类解耦,无需修改原来的代码;

2)灵活性和扩展性好,符合“开闭原则”;

3)对于Java这种不支持多重继承的语言,一次最多只能适配一个适配者类,而且目标抽象类只能为抽象类,不能为具体类,其使用有一定的局限性,不能将一个适配者类和它的子类都适配到目标接口。

2、适用场景

1)系统需要使用现有的类,而这些类的接口不符合系统的需要;

2)想要建立一个可以重复使用的类,用于与一些彼此之间没有太大关联的一些类,包括一些可能在将来引进的类一起工作。

ps

不知道大家平时用什么工具画UML,刚刚网上找了一个JUDE-Community,基本功能都有,也比较Q,符合我的审美,但是各个图、组建对齐好像没有快捷键,线也没有像PowerDesigner一样可以指定角度,每次都得自己移动鼠标调整,有点麻烦。

 

posted @ 2013-05-05 14:26  leealways87  阅读(400)  评论(0编辑  收藏  举报