Skip to content

单例、工厂和策略怎么用在前端? ​

单例保证一个过程里只有一份实例,例如唯一的请求客户端。工厂按类型创建对象,调用方不写一串构造分支。策略把可以互换的算法放进各自的函数,用键选中一个,而不是越来越长的 if。

原理 ​

单例:

js
let client = null
function getClient() {
  if (!client) client = createClient()
  return client
}

模块本身只执行一次,所以模块级变量常常就是单例。测试时要能换掉它,否则所有用例共享状态。

工厂:createRenderer(type) 内部选择画布或 SVG 的实现,返回统一接口。新增一种类型时改工厂,而不是改每个调用点。类型如果会无限增长,再考虑注册表,而不是把工厂写成中心开关。

策略:校验规则、折扣、排序比较器都是函数。上下文只负责拿到当前策略并调用。策略不应当偷偷依赖页面上的全局状态。

这三个都是为了把变化收进一个地方。只有一种实现时,不要提前包工厂。

追问 ​

单例和全局变量的差别?

单例控制创建时机和访问入口。随手挂到 window 上谁都能改,也没有初始化顺序。模块私有、只导出获取函数,才谈得上单例。

和依赖注入的关系?

工厂决定创建哪一个。注入决定这个实例从外面传进来,方便测试替换。组件的 props 就是一种注入。

易错点 ​

  • 单例里缓存了用户数据,换账号后还是上一个人。
  • 工厂返回的对象接口不统一,调用方还得再判断类型。
  • 策略函数修改了传入的对象,下一个策略看到脏数据。

相关 ​