关键在于用工厂函数为每个插件实例创建独立闭包作用域,确保配置私有、不可跨实例访问,避免单例共享;通过注入driver实现环境解耦,支持多平台复用。

关键不是把配置挂到对象上,而是让每个插件实例拥有自己独立的作用域,配置变量只在该作用域内可访问、不可跨实例读写。
用工厂函数替代单例导出
不要直接导出一个已初始化的插件对象,那样所有调用方共享同一份配置。应导出一个接收租户标识或配置参数的工厂函数,每次调用都生成全新闭包:
- 传入 tenantId、API 地址、超时时间等专属参数
- 内部声明 const config = { ... }、let cache = new Map() 等私有状态
- 返回的对象方法(如 send()、init())仍能访问这些变量,但无法被外部触达
- 不同租户调用 factory({ tenantId: 'a' }) 和 factory({ tenantId: 'b' }),得到两个完全隔离的实例
避免配置“快照化”暴露
别把配置对象直接挂到返回值上,例如 return { config: privateConfig } —— 这会让外部拿到原始引用,可能被意外修改。正确做法是:
- 配置仅用于内部逻辑,不对外暴露原始结构
- 如需读取,提供只读接口:getConfig() 返回深拷贝或精简视图
- 敏感字段(如 token、secret)绝不出现在返回对象中
- 所有方法调用都隐式绑定当前闭包上下文,无需手动传 config
结合模块模式封装初始化与工具逻辑
在工厂函数内部,可一并处理配置校验、默认值填充、异步预加载等操作,这些都属于该实例的私有生命周期:
- IIFE 或函数体开头做一次性的配置检查和资源准备
- 定义仅内部使用的辅助函数,如 _normalizeUrl()、_maskLog()
- 缓存结果(如 schema、权限列表)也保存在闭包内,不污染全局
- destroy() 方法负责清理本实例持有的定时器、事件监听、缓存引用
支持跨环境驱动契约而非硬编码依赖
配置隔离不只是数据层面,还包括行为层面。插件不应直接调用 fetch 或 localStorage,而应通过注入方式获得受控能力:
- 工厂函数接受 driver 对象:{ request, storage, logger }
- driver 由宿主环境按需提供(Web 用 fetch,Node.js 用 axios,小程序用 wx.request)
- 闭包内所有 I/O 操作都走 driver 接口,配置与执行环境彻底解耦
- 同一套插件代码可在不同平台复用,且各实例的 driver 实例互不影响
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











