ArkTS中单例模式的实现与实践

在HarmonyOS 5.0及之后的ArkTS开发中,单例模式作为一种常用的设计模式,广泛应用于全局唯一对象的管理、资源复用、配置管理等场景。本文将系统梳理ArkTS中可用的单例实现方式,并结合多线程与模块化开发的实际需求,给出可执行的最小示例代码,帮助开发者在实际项目中灵活选用。

一、饿汉式单例(Eager Singleton)

饿汉式单例在类加载时即创建实例,保证了线程安全。其优点是实现简单,缺点是无论是否用到,实例始终存在,可能造成资源浪费。适用于轻量、频繁使用的全局对象。

export class EagerSingleton {
  private static instance: EagerSingleton = new EagerSingleton();

  private constructor() {}

  static getInstance(): EagerSingleton {
    return EagerSingleton.instance;
  }

  public sayHello() {
    console.log('Hello from EagerSingleton');
  }
}

// 使用
const singleton1 = EagerSingleton.getInstance();
singleton1.sayHello();

二、懒汉式单例(Lazy Singleton)

懒汉式单例在第一次调用时才创建实例,节省了资源。但在多线程环境下,若无额外同步措施,可能导致创建多个实例。适用于对象创建开销较大、并发访问较少的场景。

export class LazySingleton {
  private static instance: LazySingleton | undefined;

  private constructor() {}

  static getInstance(): LazySingleton {
    if (!LazySingleton.instance) {
      LazySingleton.instance = new LazySingleton();
    }
    return LazySingleton.instance;
  }

  public sayHello() {
    console.log('Hello from LazySingleton');
  }
}

// 使用
const singleton2 = LazySingleton.getInstance();
singleton2.sayHello();

三、模块单例(Module Singleton)

在ArkTS中,模块本身就是天然的单例。通过导出对象,可以保证全局唯一性。这种方式适合工具类、配置类等无需复杂生命周期管理的场景。

class ModuleSingleton {
  sayHello() {
    console.log('Hello from ModuleSingleton');
  }
}

export const moduleSingleton = new ModuleSingleton();

注:此方式如果项目较为复杂有一点风险,有同步和异步获取不建议使用。有可能会出现未初始化(Error message: xxx is not initialized)的问题。


四、多线程与Sendable单例

在HarmonyOS的TaskPool和worker多线程模型中,每个线程拥有独立的内存空间,线程间通过消息传递机制通信,不能直接访问彼此的内存。为保证数据安全与一致性,ArkTS引入了@Sendable机制,允许开发者声明可安全跨线程传递的数据结构。
详细文档可参考官方指南

// 共享模块sharedModule.ets
import { ArkTSUtils } from '@kit.ArkTS';

// 声明当前模块为共享模块,只能导出可Sendable数据
"use shared"
// 共享模块,SingletonA全局唯一
@Sendable
class SingletonA {
  private count_: number = 0;
  lock_: ArkTSUtils.locks.AsyncLock = new ArkTSUtils.locks.AsyncLock()

  public async getCount(): Promise<number> {
    return this.lock_.lockAsync(() => {
      return this.count_;
    })
  }

  public async increaseCount() {
    await this.lock_.lockAsync(() => {
      this.count_++;
    })
  }
}

export let singletonA = new SingletonA();

小结
ArkTS为开发者提供了多种单例实现方式,涵盖了单线程与多线程、模块化开发等多种场景。开发者可根据实际需求,选择合适的单例实现方式,既保证了代码的简洁性,也提升了系统的健壮性和可维护性。


Logo

讨论HarmonyOS开发技术,专注于API与组件、DevEco Studio、测试、元服务和应用上架分发等。

更多推荐