设计模式之适配器模式

本文介绍了适配器模式,它能将一个类的接口转换成客户希望的另一个接口,使不兼容的类一起工作。阐述了其结构,包括目标接口、适配器和源角色,介绍了默认、对象和类适配器模式的实现方式,分析了优缺点,还对比了适配器模式和代理模式的异同。

适配器模式:将一个类的接口转换成客户希望的另一个接口。适配器模式让那些接口不兼容的类可以一起工作

结构

适配器模式中通常包括三类角色:
1:Target(目标接口):目标抽象类定义客户所需的接口,可以是一个抽象类或接口,也可以是具体类。在类适配器中,由于C#语言不支持多重继承,所以它只能是接口。

2:Adapter(适配器):它可以调用另一个接口,作为一个转换器,对Adaptee和Target进行适配。它是适配器模式的核心。

3:Adaptee(源角色):适配者即被适配的角色,也就是需要适配的对象,它定义了一个已经存在的接口,这个接口需要适配,适配者类包好了客户希望的业务方法。

实现方式:

  • 默认适配器模式:

默认适配器模式

首先,我们先看看最简单的适配器模式默认适配器模式(Default Adapter)是怎么样的。

我们用 Appache commons-io 包中的 FileAlterationListener 做例子,此接口定义了很多的方法,用于对文件或文件夹进行监控,一旦发生了对应的操作,就会触发相应的方法。

public interface FileAlterationListener {
    void onStart(final FileAlterationObserver observer);
    void onDirectoryCreate(final File directory);
    void onDirectoryChange(final File directory);
    void onDirectoryDelete(final File directory);
    void onFileCreate(final File file);
    void onFileChange(final File file);
    void onFileDelete(final File file);
    void onStop(final FileAlterationObserver observer);
}

此接口的一大问题是抽象方法太多了,如果我们要用这个接口,意味着我们要实现每一个抽象方法,如果我们只是想要监控文件夹中的文件创建和文件删除事件,可是我们还是不得不实现所有的方法,很明显,这不是我们想要的。

所以,我们需要下面的一个适配器,它用于实现上面的接口,但是所有的方法都是空方法,这样,我们就可以转而定义自己的类来继承下面这个类即可。

public class FileAlterationListenerAdaptor implements FileAlterationListener {
 
    public void onStart(final FileAlterationObserver observer) {
    }
 
    public void onDirectoryCreate(final File directory) {
    }
 
    public void onDirectoryChange(final File directory) {
    }
 
    public void onDirectoryDelete(final File directory) {
    }
 
    public void onFileCreate(final File file) {
    }
 
    public void onFileChange(final File file) {
    }
 
    public void onFileDelete(final File file) {
    }
 
    public void onStop(final FileAlterationObserver observer) {
    }
}

比如我们可以定义以下类,我们仅仅需要实现我们想实现的方法就可以了:

public class FileMonitor extends FileAlterationListenerAdaptor {
    public void onFileCreate(final File file) {
        // 文件创建
        doSomething();
    }
 
    public void onFileDelete(final File file) {
        // 文件删除
        doSomething();
    }
}
  • 对象适配器模式:

在这里插入图片描述

  • 类适配器模式:

在这里插入图片描述
通过继承的方法,适配器自动获得了所需要的大部分方法。这个时候,客户端使用更加简单,直接 Target t = new SomeAdapter(); 就可以了。

类适配和对象适配的异同

一个采用继承,一个采用组合;

类适配属于静态实现,对象适配属于组合的动态实现,对象适配需要多实例化一个对象。

总体来说,对象适配用得比较多。

优缺点

优点:

1:将目标类和适配者类解耦,通过引入一个适配器类来重用现有的适配者类,无需修改原有结构。

2:增加了类的透明性和复用性,将具体的业务实现过程封装在适配者类中,对于客户端类而言是透明的,而且提高了适配者的复用性,同一适配者类可以在多个不同的系统中复用。

3:灵活性和扩展性都非常好,通过使用配置文件,可以很方便的更换适配器,也可以在不修改原有代码的基础上 增加新的适配器,完全复合开闭原则。

缺点:

1:一次最多只能适配一个适配者类,不能同时适配多个适配者。

2:适配者类不能为最终类

3:目标抽象类只能为接口,不能为类,其使用有一定的局限性。

附:适配器模式和代理模式的异同

比较这两种模式,其实是比较对象适配器模式和代理模式,在代码结构上,它们很相似,都需要一个具体的实现类的实例。但是它们的目的不一样,代理模式做的是增强原方法的活;适配器做的是适配的活,为的是提供“把鸡包装成鸭,然后当做鸭来使用”,而鸡和鸭它们之间原本没有继承关系。
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值