跨平台开发下的策略模式

跨平台开发的核心目标是实现一套业务逻辑在多平台高效运行。

但底层 API、文件系统、权限机制等平台特性的差异,给代码维护带来了巨大挑战。

直接在业务代码中嵌入大量 if/else 进行平台判断,会导致代码耦合严重、扩展性差,最终演变为难以维护的 "面条代码"。

常见的跨平台差异点

跨平台开发中需要处理的典型差异包括:

  • 文件系统:路径分隔符(/\)、文件编码、权限管理机制。
  • 网络交互:平台 SDK 差异、请求处理方式、安全策略。
  • UI 渲染:原生控件体系、Web 视图集成、分辨率适配。
  • 系统服务:通知机制、定位服务、蓝牙等硬件交互。

使用策略模式

策略模式通过分离抽象与实现,完美解决跨平台开发中的适配问题:

  • 定义统一接口:抽象出平台无关的行为契约,使高层模块只关注 "做什么",无需关心 "怎么做"。
  • 平台特定实现:为每个平台提供独立的策略类,封装具体实现细节,新增平台时无需修改现有代码。
  • 动态策略选择:高层模块依赖抽象接口,可在运行时根据环境自动选择或动态切换策略实现。

示例:跨平台文件系统适配

1. 定义抽象接口

首先定义文件系统操作的抽象接口,屏蔽各平台差异:

export interface IFileSystem {
  writeFile(path: string, content: string): Promise<void>
  readFile(path: string): Promise<string>
  deleteFile(path: string): Promise<void>
  createFolder(path: string): Promise<void>
  deleteFolder(path: string): Promise<void>
}

2. 实现平台特定策略

为各平台实现具体策略类,封装平台特有逻辑:

// Windows平台实现
export class WindowsFileSystem implements IFileSystem {
  async writeFile(path: string, content: string): Promise<void> {
    // Windows特定文件写入逻辑
  }
  
  // 其他方法实现...
}

// Linux平台实现
export class LinuxFileSystem implements IFileSystem {
  async writeFile(path: string, content: string): Promise<void> {
    // Linux特定文件写入逻辑
  }
  
  // 其他方法实现...
}

// macOS平台实现
export class MacFileSystem implements IFileSystem {
  async writeFile(path: string, content: string): Promise<void> {
    // macOS特定文件写入逻辑
  }
  
  // 其他方法实现...
}

3. 策略工厂与访问封装

使用工厂模式管理策略实例,配合单例模式确保全局一致性:

这里使用单例模式是因为平台是固定的,不会变化,不可能说程序在 Windows 运行到一半突然切换到 Linux 去。

type PlatformType = 'win32' | 'linux' | 'darwin'

// 策略工厂:负责创建平台对应的策略实例
class FileSystemStrategyFactory {
  static createStrategy(): IFileSystem {
    const platform = process.platform as PlatformType;
  
    const strategies: Record<PlatformType, new () => IFileSystem> = {
      win32: WindowsFileSystem,
      linux: LinuxFileSystem,
      darwin: MacFileSystem
    };
  
    const StrategyClass = strategies[platform];
    if (!StrategyClass) {
      throw new Error(`Unsupported platform: ${platform}`);
    }
  
    return new StrategyClass();
  }
}

// 对外暴露的文件系统服务
export class FileSystemService {
  private static instance: FileSystemService;
  private strategy: IFileSystem;
  
  // 私有构造函数确保只能通过getInstance创建
  private constructor() {
    this.strategy = FileSystemStrategyFactory.createStrategy();
  }
  
  // 单例模式获取服务实例
  static getInstance(): FileSystemService {
    if (!FileSystemService.instance) {
      FileSystemService.instance = new FileSystemService();
    }
    return FileSystemService.instance;
  }
  
  // 代理策略方法,对外提供统一接口
  async writeFile(path: string, content: string): Promise<void> {
    return this.strategy.writeFile(path, content);
  }
  
  async readFile(path: string): Promise<string> {
    return this.strategy.readFile(path);
  }
  
  async deleteFile(path: string): Promise<void> {
    return this.strategy.deleteFile(path);
  }
  
  async createFolder(path: string): Promise<void> {
    return this.strategy.createFolder(path);
  }
  
  async deleteFolder(path: string): Promise<void> {
    return this.strategy.deleteFolder(path);
  }
}

跨平台开发下的策略模式
http://www.inksha.com/archives/kua-ping-tai-kai-fa-xia-de-ce-lue-mo-shi
作者
inksha
发布于
2025年08月15日
许可协议