官术网_书友最值得收藏!

Singleton

The Singleton pattern is perhaps the most overused pattern. It is also a pattern that has fallen out of favor in recent years. To see why people are starting to advise against using Singleton, let's take a look at how the pattern works.

Singleton is used when a global variable is desirable, but Singleton provides protection against accidentally creating multiple copies of a complex object. It also allows for the deferral of object instantiation until the first use.

The UML diagram for Singleton is as follows:

It is clearly a very simple pattern. The Singleton pattern acts as a wrapper around an instance of the class and the Singleton itself lives as a global variable. When accessing the instance, we simply ask Singleton for the current instance of the wrapped class. If the class does not yet exist within the Singleton, it is common to create a new instance at that time.

Implementation

Within our ongoing example in the world of Westeros, we need to find a case where there can only ever be one of an item. Unfortunately, it is a land with frequent conflicts and rivalries, and so my first idea of using the king as the Singleton pattern is simply not going to fly. This split also means that we cannot make use of any of the other obvious candidates (capital city, queen, general…) as there may be many instances of each of those too. However, in the far north of Westeros, there is a giant wall constructed to keep an ancient enemy at bay. There is only one of these walls and it should pose no issue having it in the global scope.

Let's go ahead and create a Singleton class in JavaScript:

var Westeros;
(function (Westeros) {
  var Wall = (function () {
 function Wall() {
 this.height = 0;
 if (Wall._instance)
 return Wall._instance;
 Wall._instance = this;
 }
    Wall.prototype.setHeight = function (height) {
      this.height = height;
    };
    Wall.prototype.getStatus = function () {
      console.log("Wall is " + this.height + " meters tall");
    };
    Wall.getInstance = function () {
 if (!Wall._instance) {
 Wall._instance = new Wall();
 }
 return Wall._instance;
 };
    Wall._instance = null;
    return Wall;
  })();
  Westeros.Wall = Wall;
})(Westeros || (Westeros = {}));

The code creates a lightweight representation of the Wall class. The Singleton pattern is demonstrated in the two highlighted sections. In a language like C# or Java, we would normally just set the constructor to be private so that it could only be called by the static getInstance method. However, we don't have that ability in JavaScript: constructors cannot be private. Thus, we do the best we can and return the current instance from the constructor. This may appear strange, but in the way we've constructed our classes the constructor is no different from any other method, so it is possible to return something from it.

In the second highlighted section, we set a static variable, _instance, to be a new instance of Wall when one is not already there. In the case that _instance already exists, we return that. In C# and Java, there will be a need for some complicated locking logic in this function to avoid race conditions as two different threads attempt to access the instance at the same time. Fortunately, there is no need to worry about this in JavaScript, where the multithreading story is different.

Disadvantages

Singletons have gained a somewhat bad reputation in the last few years. They are, in effect, glorified global variables. As we've discussed, global variables are ill conceived and the potential cause of numerous bugs. They are also difficult to test with unit tests, as the creation of the instance cannot easily be overridden. The single largest concern I have with them is that singletons have too much responsibility. They control not just themselves but also their instantiation. This is a clear violation of the single responsibility principle. Almost every problem that can be solved by using a Singleton pattern is better solved using some other mechanism.

JavaScript makes the problem even worse. It isn't possible to create a clean implementation of the Singleton pattern due to the restrictions on the constructor. This, coupled with the general problems around the Singleton pattern, lead me to suggest that this pattern should be avoided in JavaScript.

主站蜘蛛池模板: 明溪县| 公安县| 五常市| 福州市| 合肥市| 永年县| 马尔康县| 民权县| 文安县| 皮山县| 南宁市| 长海县| 安岳县| 萝北县| 东光县| 大新县| 海淀区| 张家界市| 德安县| 巴塘县| 蒙自县| 同德县| 湖州市| 海阳市| 二手房| 沾化县| 鱼台县| 朝阳区| 泰宁县| 墨江| 克什克腾旗| 合阳县| 旬阳县| 贵港市| 瑞昌市| 萍乡市| 临江市| 淮北市| 梁河县| 平南县| 石狮市|