设计模式-适配器模式

请直接看原文:

秒懂设计模式之适配器模式(Adapter Pattern) - 知乎 (zhihu.com)


设计模式汇总篇,一定要收藏:

永不磨灭的设计模式 - ShuSheng007​shusheng007.top/2021/09/07/design-pattern/​编辑

概述

由于面向对象程序设计本身就是从实际生活中汲取的灵感,将大千世界抽象到程序设计领域,所以所有的设计模式都是可以在日常生活中感受的到的。例如适配器模式,这个在日常生活中就太普遍了。 例如我们程序员经常遇到的电脑上提供的端口与要插入的接头匹配不上,而我们则可以通过一个中间的适配器将两边连接起来。

这个设计模式在日常开发中出镜率极高,关键还不难,所以兄弟们一定要掌握啊。

类型

结构型(structural)

难度

1颗星

定义

将一个接口转换为客户端所期待的接口,从而使两个接口不兼容的类可以在一起工作

适配器模式还有个别名叫:Wrapper(包装器),顾名思义就是将目标类用一个新类包装一下,相当于在客户端与目标类直接加了一层。IT世界有句俗语:没有什么问题是加一层不能解决的

使用场景

  • 当需要使用一个现存的类,但它提供的接口与我们系统的接口不兼容,而我们还不能修改它时
  • 当多个团队独立开发系统的各功能模块,然后组合在一起,但由于某些原因事先不能确定接口时。(别和我说这不可能,这太tm可能了)

UML类图

照例先上一张俺手撕的UML类图

从上图可见,适配器模式只有3个角色

  • Target

是一个接口,它是我们客户端使用的目标接口

  • Adaptee

我们想要使用的接口与Target不兼容的类,它可以是一个接口,也可以是一个类。

  • Adapter

适配器类,此模式的核心。它需要实现目标接口Target,而且必须要引用Adaptee,因为我们要在此类中包装Adaptee的功能

实例

最近王二狗工作上遇到了一件非常不开心的事:由于老项目中的日志系统非常粗糙,导致他debug时候非常吃力,为此都加了好几次班了,媳妇都不高兴了。某天,二狗又一次披星戴月的回到家中,蹑手蹑脚脱了衣服慢慢爬上床时,此时只听的床头那边幽幽的传来一声抱怨:二狗,你天天忙着调试bug,你就不担心你媳妇被隔壁老王调试了?

二狗深感不安,决定彻底扭转这个不利的局面。于是他调研了一个非常棒的三方开源日志库来改进项目的log系统,但是此开源库与项目中接口不兼容,这几乎是肯定的,所以王二狗又一次展现出了其高超的程序设计能力,精准的采用了适配器模式来完成这个功能。

第一,确定目标接口

系统原来的日志接口如下

java 复制代码
public interface LogFactory {
    void debug(String tag,String message);
}

第二,三方库接口及实现

下面是第三方库提供的日志功能,但是其接口与二狗他们系统目前使用的不兼容。

java 复制代码
public interface NbLogger {
    void d(int priority, String message, Object ... obj);
}
//具体提供日志功能的实现类
public class NbLoggerImp implements NbLogger {
    @Override
    public void d(int priority, String message, Object... obj) {
        System.out.println(String.format("牛逼logger记录:%s",message));
    }
}

第三,构建适配器类

这个类是适配器模式的核心,通过此类就可以将三方库提供的接口转换为系统的目标接口

java 复制代码
public class LogAdapter implements LogFactory {
    private NbLogger nbLogger;

    public LogAdapter(NbLogger nbLogger) {
        this.nbLogger = nbLogger;
    }

    @Override
    public void debug(String tag, String message) {
        Objects.requireNonNull(nbLogger);
        nbLogger.d(1, message);
    }
}

LogAdapter实现了系统的目标接口,同时持有三方库NbLogger的引用。

第四,客户端使用

java 复制代码
public class AdapterClient {
    public void recordLog() {
        LogFactory logFactory = new LogAdapter(new NbLoggerImp());
        logFactory.debug("Test", "我将使用牛逼logger打印log");
    }
}

可以看到,通过适配器客户端就可以很轻松的切换到新的日志系统了。

技术要点总结

  • 适配器LogAdapter 必须要实现目标接口,且依赖那个提供功能的类型,此处为NbLogger

优缺点

优点

  • 极大的增强了程序的可扩展性,通过此模式,你可以随意扩展程序的功能,但却不需要修改接口

缺点

  • 其实在我看来这个模式真没啥缺点,唯一可以称的上的缺点是多了一层,但是这也是没有办法的事情。
相关推荐
刷帅耍帅1 小时前
设计模式-桥接模式
设计模式·桥接模式
MinBadGuy2 小时前
【GeekBand】C++设计模式笔记5_Observer_观察者模式
c++·设计模式
刷帅耍帅3 小时前
设计模式-生成器模式/建造者模式Builder
设计模式·建造者模式
蜡笔小新..1 天前
【设计模式】软件设计原则——开闭原则&里氏替换&单一职责
java·设计模式·开闭原则·单一职责原则
性感博主在线瞎搞1 天前
【面向对象】设计模式概念和分类
设计模式·面向对象·中级软件设计师·设计方法
lucifer3111 天前
JavaScript 中的组合模式(十)
javascript·设计模式
lucifer3111 天前
JavaScript 中的装饰器模式(十一)
javascript·设计模式
蜡笔小新..1 天前
【设计模式】软件设计原则——依赖倒置&合成复用
设计模式·依赖倒置原则·合成复用原则
刷帅耍帅1 天前
设计模式-代理模式
设计模式·代理模式
神的孩子都在歌唱2 天前
行为设计模式 -观察者模式- JAVA
java·观察者模式·设计模式