• JavaScript 设计模式系列 : 单例(Singleton)模式


    单例(SIngleton)模式:

      功能:   用来划分命名空间:

          1.减少网页中的全局变量的数量。

          2.可以在多人开发时避免代码命名冲突。

          3.一是某个类只能有一个实例;二是它必须自行创建这个实例;三是它必须自行向整个系统提供这个实例。

    在JavaScript里,单例作为一个命名空间提供者,从全局命名空间里提供一个唯一的访问点来访问该对象。单例模式就是用一个命名空间包含自己的所有代码的全局对象。在传统工程师眼中,单例就是保证一个类只有一个实例,实现的方法一般是先判断实例存在与否,如果存在直接返回,如果不存在就创建了再返回,这就确保了一个类只有一个实例对象。示例:

    1.对象字面量方法

    1 var functionFree = {
    2     name:'free',
    3     method:function(){
    4           //code
    5     },
    6     init:function(){
    7           //code
    8     }
    9 }

    或者:使用实例化构造函数的方法

    1 var functionFree = new  function myGroup(){
    2      this.name = 'free',
    3      this.getName = function(){
    4      
    5       }
    6       ...
    7 }

    立即执行函数创建单体:

     1 var Singleton = function(){//这个匿名函数返回一个对象,将这个对象//赋值给Singleton
     2       return {};
     3 }();
     4 
     5 var Singleton = (function(){//这是声明之后立即调用
     6      return {};
     7 }());
     8 
     9 var Singleton = (function(){//这是声明之后立即调用
    10      return {};
    11 })();

    2.扩展:如果要扩展对象,可以自定义私有成员和方法,然后使用闭包在内部封装这些变量和函数。暴露你想暴露的方法。

        闭包实现内部方法外部调用。这种模式又叫做模块模式(module pattern)。

     1 var mySingleton = function () {   
     2     /* 这里声明私有变量和方法 */    
     3        var privateVariable = 'something private';    
     4        function showPrivate() {        
     5             console.log(privateVariable);    
     6        }   
     7        /* 公有变量和方法(可以访问私有变量和方法) */    
     8        return {        
     9          publicMethod: function () {            
    10             showPrivate();        
    11           },        
    12           publicVar: 'the public can see this!'    
    13      };
    14  };
    15  var single = mySingleton();
    16  single.publicMethod();  // 输出 'something private'
    17  console.log(single.publicVar); // 输出 'the public can see this!'

    3.用公有方法调用单例,在需要的时候才来初始化。将单例的代码放在init()函数中,第一次调用的时候才会实例化。

     1 var Singleton = (function () {
     2     var instantiated;
     3     function construct() {//将所有的单例代码放到这个construct函数中间来。这里不能从外部访问。我们需要一个公有的方法getInstance方法来返回这个方法。
     4         /*这里定义单例代码*/
     5         var param = "free";
     6         method1 = function(){
     7 
     8         }
     9         return {
    10             publicMethod: function () {
    11                 console.log('hello world');
    12             },
    13             publicProperty: 'test'
    14         };
    15     }
    16 
    17     return {
    18         getInstance: function () {
    19             if (!instantiated) {//判断类是否实例化
    20                 instantiated = construct();//对象
    21             }
    22             return instantiated;
    23         }
    24     };
    25 })();
    26 
    27 /*调用公有的方法来获取实例:*/
    28 Singleton.getInstance().publicMethod();

    其实单例一般是用在系统间各种模式的通信协调上,下面的代码是一个单例的最佳实践:

       外围是一个立即调用的函数,然后是一个构造函数,通过new生成一个单例instance,通过getInstance()传递进去参数,同时调用单例。

    var SingletonTester = (function () {

    //参数:传递给单例的一个参数集合
    function Singleton(args) {

    //设置args变量为接收的参数或者为空(如果没有提供的话)
    var args = args || {};
    this.name = 'SingletonTester';
    this.pointX = args.pointX || 6; //从接收的参数里获取,或者设置为默认值
    this.pointY = args.pointY || 10;

    }

    //实例容器
    var instance;

    var _static = {
    name: 'SingletonTester',

    //获取实例的方法
    //返回Singleton的实例
    getInstance: function (args) {
    if (instance === undefined) {
    instance = new Singleton(args);//实例化成对象调用
    }
    return instance;
    }
    };
    return _static;
    })();

    var singletonTest = SingletonTester.getInstance({ pointX: 5 });
    console.log(singletonTest.pointX); // 输出 5

     4>>分支:返回需要的对象,而不管具体含有多少对象。最终只实例化需要的对象。

     1 Singleton = (function(){
     2       var objectA = {
     3              method1:function(){...},
     4              method2:function(){...},
     5        };
     6       var objectB = {
     7              method1:function(){...},
     8              method2:function(){...},
     9        };
    10        return (someCondition) ? objectA : objectB;
    11 })();
  • 相关阅读:
    第四周作业
    第三周作业
    第二周基础作业
    抓老鼠
    币值转换
    打印沙漏
    秋季学期学习总结
    2019春第七周作业
    2019春第六周作业 学习总结
    第五周作业总结以及学习总结
  • 原文地址:https://www.cnblogs.com/colorstory/p/2588413.html
Copyright © 2020-2023  润新知