您现在的位置是:网站首页 > 多端统一开发中的模式适配文章详情

多端统一开发中的模式适配

多端统一开发中的模式适配

多端统一开发的核心在于如何高效复用代码逻辑,同时优雅处理不同平台的差异性。模式适配通过抽象与封装,将通用逻辑与平台特性解耦,使得一套代码能够动态适应Web、小程序、Native等终端环境。这种场景下,设计模式的价值尤为凸显。

适配器模式处理API差异

跨平台开发中最常见的挑战是基础API的差异。例如文件系统操作在Web端使用FileReader,而微信小程序则使用wx.getFileSystemManager()。适配器模式通过中间层抹平差异:

// 通用文件读取适配器
class FileSystemAdapter {
  constructor(platform) {
    this.platform = platform;
  }

  readFile(path) {
    switch (this.platform) {
      case 'web':
        return new Promise((resolve) => {
          const reader = new FileReader();
          reader.onload = () => resolve(reader.result);
          reader.readAsText(path);
        });
      case 'wx':
        return wx.getFileSystemManager().readFileSync(path);
      case 'node':
        return require('fs').promises.readFile(path, 'utf-8');
    }
  }
}

// 使用示例
const webAdapter = new FileSystemAdapter('web');
webAdapter.readFile(fileInput.files[0]).then(console.log);

这种实现方式将平台相关代码集中管理,业务层只需调用统一接口。当新增React Native支持时,只需扩展适配器而无需修改调用方代码。

桥接模式分离抽象与实现

多端UI渲染往往需要处理不同平台的组件体系。桥接模式通过分离组件抽象与具体实现,使得组件逻辑可以跨平台复用:

// 抽象部分 - 定义业务逻辑
class Modal {
  constructor(implementation) {
    this.impl = implementation;
  }

  show(title, content) {
    this.impl.render(title, content);
    this.impl.bindEvents();
  }
}

// 实现部分 - 平台具体实现
class WebModalImpl {
  render(title, content) {
    this.element = document.createElement('div');
    this.element.innerHTML = `
      <div class="modal">
        <h2>${title}</h2>
        <div>${content}</div>
      </div>
    `;
    document.body.appendChild(this.element);
  }

  bindEvents() {
    this.element.addEventListener('click', () => this.close());
  }
}

class WxModalImpl {
  render(title, content) {
    wx.showModal({ title, content });
  }

  bindEvents() {
    // 小程序API已内置事件处理
  }
}

// 使用示例
const webModal = new Modal(new WebModalImpl());
webModal.show('提示', '操作成功');

策略模式动态选择平台方案

对于需要运行时动态切换的场景,策略模式配合环境检测能实现灵活的多端适配:

const platformStrategies = {
  web: {
    navigate: (path) => window.location.assign(path),
    storage: {
      set: (key, val) => localStorage.setItem(key, val),
      get: (key) => localStorage.getItem(key)
    }
  },
  wx: {
    navigate: (path) => wx.navigateTo({ url: path }),
    storage: {
      set: (key, val) => wx.setStorageSync(key, val),
      get: (key) => wx.getStorageSync(key)
    }
  }
};

class CrossPlatformSDK {
  constructor() {
    this.platform = detectPlatform(); // 返回'web'/'wx'等
    this.strategy = platformStrategies[this.platform];
  }

  navigateTo(path) {
    this.strategy.navigate(path);
  }

  setStorage(key, value) {
    this.strategy.storage.set(key, value);
  }
}

// 环境检测示例
function detectPlatform() {
  if (typeof wx !== 'undefined') return 'wx';
  if (typeof window !== 'undefined') return 'web';
  return 'unknown';
}

抽象工厂创建平台相关对象

当需要构建整套平台相关组件时,抽象工厂模式能保证组件之间的兼容性:

// 抽象工厂接口
class UIComponentsFactory {
  createButton() {}
  createModal() {}
}

// Web具体工厂
class WebComponentsFactory extends UIComponentsFactory {
  createButton(text) {
    return new WebButton(text);
  }
  createModal() {
    return new WebModal();
  }
}

// 小程序具体工厂
class WxComponentsFactory extends UIComponentsFactory {
  createButton(text) {
    return new WxButton(text);
  }
  createModal() {
    return new WxModal();
  }
}

// 产品实现
class WebButton {
  constructor(text) {
    this.element = document.createElement('button');
    this.element.textContent = text;
  }
}

class WxButton {
  constructor(text) {
    return { type: 'button', text };
  }
}

// 使用示例
function getFactory(platform) {
  const factories = {
    web: WebComponentsFactory,
    wx: WxComponentsFactory
  };
  return new factories[platform]();
}

const factory = getFactory('wx');
const button = factory.createButton('提交');

观察者模式实现跨端事件同步

在多端协同场景下(如Web与移动端实时同步),观察者模式能有效处理状态变更:

class CrossPlatformEventBus {
  constructor() {
    this.subscribers = [];
  }

  subscribe(callback) {
    this.subscribers.push(callback);
  }

  publish(data) {
    this.subscribers.forEach(cb => cb(data));
  }

  // 平台特定的事件绑定
  setupWebListeners() {
    window.addEventListener('online', () => this.publish({ type: 'NETWORK_CHANGE' }));
  }

  setupWxListeners() {
    wx.onNetworkStatusChange(res => {
      this.publish({ type: 'NETWORK_CHANGE', isConnected: res.isConnected });
    });
  }
}

// 使用示例
const bus = new CrossPlatformEventBus();
bus.setupWebListeners();
bus.subscribe(event => {
  if (event.type === 'NETWORK_CHANGE') {
    showNetworkStatus(event.isConnected);
  }
});

代理模式处理能力降级

在低版本或能力受限的平台,代理模式可以实现优雅降级:

// 完整功能实现
class FullFeatureService {
  scanQRCode() {
    return new Promise((resolve) => {
      wx.scanCode({ success: res => resolve(res.result) });
    });
  }
}

// 降级代理
class DegradeServiceProxy {
  constructor() {
    try {
      this.service = new FullFeatureService();
    } catch (e) {
      this.service = null;
    }
  }

  scanQRCode() {
    if (!this.service) {
      return Promise.resolve(
        prompt('当前环境不支持扫码,请输入二维码内容')
      );
    }
    return this.service.scanQRCode();
  }
}

// 使用示例
const scanner = new DegradeServiceProxy();
scanner.scanQRCode().then(content => {
  console.log('获取内容:', content);
});

装饰器模式扩展平台功能

通过装饰器模式可以在不修改核心逻辑的前提下,为不同平台添加特有功能:

// 基础消息通知类
class BaseNotifier {
  send(message) {
    console.log('基础通知:', message);
  }
}

// 平台功能装饰器
class WxNotifyDecorator {
  constructor(notifier) {
    this.notifier = notifier;
  }

  send(message) {
    this.notifier.send(message);
    if (wx.showToast) {
      wx.showToast({ title: message, icon: 'none' });
    }
  }
}

class WebNotifyDecorator {
  constructor(notifier) {
    this.notifier = notifier;
  }

  send(message) {
    this.notifier.send(message);
    if (window.Notification?.permission === 'granted') {
      new Notification('新消息', { body: message });
    }
  }
}

// 使用示例
let notifier = new BaseNotifier();
if (typeof wx !== 'undefined') {
  notifier = new WxNotifyDecorator(notifier);
} else {
  notifier = new WebNotifyDecorator(notifier);
}
notifier.send('您有新订单');

状态模式管理平台差异

对于需要根据平台状态改变行为的场景,状态模式提供结构化解决方案:

class PlatformState {
  constructor() {
    this.currentState = null;
    this.states = {
      web: new WebState(),
      wx: new WxState(),
      rn: new RNState()
    };
  }

  setPlatform(platform) {
    this.currentState = this.states[platform];
  }

  fetch(url) {
    return this.currentState.fetch(url);
  }
}

class WebState {
  fetch(url) {
    return fetch(url).then(res => res.json());
  }
}

class WxState {
  fetch(url) {
    return new Promise((resolve) => {
      wx.request({ url, success: res => resolve(res.data) });
    });
  }
}

// 使用示例
const platform = new PlatformState();
platform.setPlatform('wx');
platform.fetch('/api/data').then(console.log);

模板方法定义多端流程

对于固定流程但步骤实现不同的场景,模板方法模式能保持流程结构统一:

abstract class PaymentProcessor {
  // 模板方法
  process(amount) {
    this.validate();
    const result = this.pay(amount);
    this.afterPay(result);
    return result;
  }

  validate() {
    // 通用验证逻辑
  }

  abstract pay(amount); // 平台实现

  afterPay(result) {
    // 默认后处理
  }
}

class WxPayment extends PaymentProcessor {
  pay(amount) {
    return wx.requestPayment({ amount });
  }
}

class WebPayment extends PaymentProcessor {
  pay(amount) {
    return fetch('/pay', { method: 'POST', body: JSON.stringify({ amount }) });
  }

  afterPay() {
    showThankYouPage();
  }
}

组合模式构建跨平台UI树

处理嵌套UI结构时,组合模式能统一简单和复杂组件的操作方式:

class UIComponent {
  constructor(type) {
    this.type = type;
    this.children = [];
  }

  add(child) {
    this.children.push(child);
  }

  render() {
    const result = { type: this.type, children: [] };
    for (const child of this.children) {
      result.children.push(child.render());
    }
    return result;
  }
}

class PlatformButton {
  constructor(text) {
    this.text = text;
  }

  render() {
    return {
      type: 'button',
      text: this.text,
      // 平台特有属性
      ...(typeof wx !== 'undefined' && { size: 'mini' })
    };
  }
}

// 使用示例
const form = new UIComponent('form');
form.add(new PlatformButton('提交'));
form.add(new PlatformButton('取消'));
console.log(form.render());

我的名片

网名:~川~

岗位:console.log 调试员

坐标:重庆市-九龙坡区

邮箱:cc@qdcc.cn

沙漏人生

站点信息

  • 建站时间:2013/03/16
  • 本站运行
  • 文章数量
  • 总访问量
微信公众号
每次关注
都是向财富自由迈进的一步