Web 技术研究所

我一直坚信着,Web 将会成为未来应用程序的主流

多次实例化的坑与单例模式

  一直看到有人把一些只允许使用一次的东西封装成普通的类。以前我也懒得喷这个点,但现在发现这种用法越来越肆无忌惮了,于是终于忍不住还是开喷了。为什么喜欢封装成类呢?如果是单例模式的话我勉强还能接受,封装成一个普通类真的不会出问题么?
  有很多东西,它们确实是唯一的。比如对于客户端而言,一个页面上的 document 对象就是唯一的。如果我们有操作 body 上 class 的需求,那么将这个需求封装成了类的做法我是可以接受的,但前提是这个类要么是单例实现要么是抽象类。如果以普通的类来实现这个功能就可能出现奇怪的问题,比如下面这个代码。 var Manager = function() {
  this.body = document.body;
  this._matcher = /(?:^| )locked(?=$| )/;
  this._isLocked = false;
};
Manager.prototype = {
  isLocked: function() {
    return this._isLocked;
  },
  lock: function() {
    if(!this._matcher.test(this.body.className)) {
      this.body.className += ' locked';
    }
    this._isLocked = true;
  },
  unlock: function() {
    var str = this.body.className;
    this.body.className = str.replace(this._matcher, '');
    this._isLocked = false;
  }
};
  这个代码的作用是管理 body 元素上的 locked 这个 className。如果可以确保这个构造器只创建一个实例那是没问题的,但如果仅仅是上面这样的代码显然没有做这些限制。所以一旦这个类被实例化多次就会出现意料之外的结果,而且还不会抛错,很难调试出来。这种时候应该将这个类以单例模式实现,或者更好的办法是将其抽取为独立的服务。
  其实我不太喜欢单例模式,虽然这个概念非常好,但在实现上通常是不科学的。如果一个类只实例化一次就足够,那么应该由另一个类来管理这件事。直接实现的单例感觉是 OOP 走火入魔了,有时候我还是更喜欢 FP 一点。
网名:
34.203.213.*
电子邮箱:
仅用于接收通知
提交 悄悄的告诉你,Ctrl+Enter 可以提交哦
神奇海螺
[查看全部主题]
各类Web技术问题讨论区
发起新主题
本模块采用即时聊天邮件通知的模式
让钛合金F5成为历史吧!
次碳酸钴的技术博客,文章原创,转载请保留原文链接 ^_^