跨平台开发的核心目标是实现一套业务逻辑在多平台高效运行。
但底层 API、文件系统、权限机制等平台特性的差异,给代码维护带来了巨大挑战。
直接在业务代码中嵌入大量 if/else 进行平台判断,会导致代码耦合严重、扩展性差,最终演变为难以维护的 "面条代码"。
常见的跨平台差异点
跨平台开发中需要处理的典型差异包括:
- 文件系统:路径分隔符(
/
与\
)、文件编码、权限管理机制。 - 网络交互:平台 SDK 差异、请求处理方式、安全策略。
- UI 渲染:原生控件体系、Web 视图集成、分辨率适配。
- 系统服务:通知机制、定位服务、蓝牙等硬件交互。
使用策略模式
策略模式通过分离抽象与实现,完美解决跨平台开发中的适配问题:
- 定义统一接口:抽象出平台无关的行为契约,使高层模块只关注 "做什么",无需关心 "怎么做"。
- 平台特定实现:为每个平台提供独立的策略类,封装具体实现细节,新增平台时无需修改现有代码。
- 动态策略选择:高层模块依赖抽象接口,可在运行时根据环境自动选择或动态切换策略实现。
示例:跨平台文件系统适配
1. 定义抽象接口
首先定义文件系统操作的抽象接口,屏蔽各平台差异:
ts
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. 实现平台特定策略
为各平台实现具体策略类,封装平台特有逻辑:
ts
// 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 去。
ts
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);
}
}