luoxue-victor / my-blog

公众号【前端技匠】作者

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

专题5: 设计模式之适配器模式

luoxue-victor opened this issue · comments

适配器模式(Adapter Pattern)是作为两个不兼容的接口之间的桥梁。这种类型的设计模式属于结构型模式,它结合了两个独立接口的功能。

优缺点

优点

  1. 可以让任何两个没有关联的类一起运行。
  2. 提高了类的复用。
  3. 增加了类的透明度。
  4. 灵活性好。

缺点

  1. 过多地使用适配器,会让系统非常零乱,不易整体进行把握。

实战

举一个例子,你要写一个页面兼容各个端的小程序,那么你就需要根据环境调用不同小程序的 sdk 方法。比如在支付宝中有一个 zhifubaoShare 的分享方法,在微信中有一个 weixinShare 的分享方法。(当然一个sdk还有很多方法,我们只拿分享来举例子)但是我们在工作中其实只希望调用一个 share 方法就能实现不同端的分享。下面我们用适配器模式来做一个 Adapter 适配器。

// =============== 定义接口与类型 ==============================
// 支付宝接口
interface ZhifubaoInerface {
  zhifubaoShare(): void;
}
// 微信接口
interface WeixinInterface {
  weixinShare(): void;
}
// adapter 接口
interface AdapterInterface {
  share(): void;
}
// 合并所有 sdk 类型
interface MergeSdk extends ZhifubaoInerface, WeixinInterface {}
// 支持的平台类型
type platform = 'weixin' | 'zhifubao';


// =============== 代码逻辑实现 ==============================
// 微信 sdk 类实现
class WeixinSdk implements WeixinInterface {
  weixinShare() {
    console.log('微信分享');
  }
}
// 支付宝 sdk 类实现
class ZhifubaoSdk implements ZhifubaoInerface {
  zhifubaoShare() {
    console.log('支付宝分享');
  }
}
// adapter 类实现
class Adapter implements AdapterInterface {
  constructor() {
    this.sdk = this.getPlatfromSdk();
  }
  // 挂载 sdk
  private sdk: MergeSdk;
  // 根据 ua 获取到平台
  private getPlatform(): platform {
    // 默认写了 weixin
    return 'weixin';
  }
  // 将所有 sdk 方法放进一个 map 里
  private getPlatfromSdk() {
    const map = {
      weixin: WeixinSdk,
      zhifubao: ZhifubaoSdk
    };
    const platform = this.getPlatform();
    return new map[platform]() as MergeSdk;
  }
  // 分享功能
  // 实际项目中还有参数的问题,这里为了代码的简洁就不写了
  public share() {
    const platform = this.getPlatform();

    switch (platform) {
      case 'weixin':
        this.sdk.weixinShare();
        break;
      case 'zhifubao':
        this.sdk.zhifubaoShare();
        break;
      default:
        console.log('此方法不存在');
    }
  }
}

const adapter = new Adapter();
// 因为我们默认设置了 weixin 平台
adapter.share(); // 微信分享