文档章节

javascript设计模式第5张--单体设计模式

Q_z
 Q_z
发布于 2014/12/24 22:56
字数 2071
阅读 144
收藏 14

单体模式的概述:
 单体是一个只能被实例化一次并且可以通过一个众所周知的访问点访问的类。
 单体是一个用来划分命名空间并将一批相关方法和属性组织在一起的对象。如果它可以被实例化,那么他只能被实例化一次。

 单体对象的区分;
  1.并非所有的对象字面量都是单体。如果他只是用来模仿关联数组或容纳数据的话,那就不是单体。
  2.如果用来组织一批相关方法和属性话。那就可能是单体。
1.单体的基本结构
 最简单的单体实际上就是一个对象字面量,它把一批有一定关联的方法和属性组织在一起
   var Singleton = {
     attribute1 : true,
     attribute2 : 10,
     method1:function(){

     },
     method2:function(){


     }
   }

   类分析:
    1.这个单体对象被修改。可以为对象添加新成员。
    2.可以使用delete运算符删除其现有成员。
    3.面向对象设计的原则:类可以被扩展,但是不能 被修改。


5.2划分命名空间
 单体对象有两部分组成:
  包含着方法和属性成员的对象自身。以及用来访问它的变量。(这个变量通常是全局性的,以便在网页上任何地方都能直接访问到它所指向的单体对象。) 这是单体模式的一个要点。
  命名空间是可靠的javascript编程的一个重要工具。
  为了避免无意中改下变量,最好的解决方法之一是用单体对象将代码组织在命名空间之中。
  var Mynamespace = {
   findProduct : function(id){

   }
  }

  分析:
    1.现在findProduct函数是一个Mynamespace的中一个方法,不会被全局命名空间中声明的任何新变量改写。
    2.用命名空间把类似的方法组织在一起。有助于增强代码的文档性。
 命名空间进一步分割。
  各种javascript代码,都有可能出现在全局命名空间中。
   为了避免冲突,可以定义一个用来包含自己的所有代码的全局对象:
    var GiantCorp = {};
   2.然后可以分闷别类地把自己的代码和数据组织到这个全局对象中的各种对象中:
   GiantCorp.Common = {

   }

5.3 用作特定网页专用代码的包装器的单体
 场景描述:
  在有很多网页网页的网站中,有些javascript代码是所有的网页都要用到的,所以他们被存放在独立的文件中,有些代码是某个网页专用的。不会被用到其他地方。
 建议:最后把这两种代码分别包装在自己的单体对象中。
 包装特定网页的专用代码的单体的骨架:
  Namespace.PageName = {
   CONSTANT_1:true,
   CONSTANT_2:10,
   method1:function(){


   },
   method2:function(){


   }

   init:function(){


   }
  }

 5.4拥有私有成员的单体
  5.4.1使用下划线表示法
   1.在单体对象内创建私有成员最简单,。最直接了当的办法是使用下划线表示法。
   2.在单体对象中使用下划线表示法是一种告诫其他程序员不要直接访问特定成员的简明方法
   GiantCorp.DataParser = {
    _stripWhitespace :function(str){
     return str.replace(/\s+/,'');

    },
    _stringSplit:function(str,delimiter){
     return str.split(delimiter)
    },
    string:function(str,delimiter,stripws){
     if(stripws);
     str = this.__stripWhitespace(str);
     var outputArray = this._stringSplit(str,delimiter);
     return outputArray;
    }

   }

  5.4.2 使用闭包
  
   在单体对象中创建私有成员的第二种方法需要借助闭包,这个和第3章中创建真正的私有成员的做法非常相似。但是有一个(重要的区别)
    1.之前的做法是吧变量和函数定义在构造函数体内,让他变成私有成员。
    2.构造函数体内定义了所有的特权方法并用this关键字使其可被外界访问。
    3.每次生成一个该类的实例时,所有的声明的构造函数内的方法和属性都会再次创建一次。
   单体模式使用闭包:
    1.单体只会被实例化一次。不用担心自己在构造函数中声明了多少成员。
    2.每个属性和方法都会被创建一次。所有可以把他们声明在构造函数内部
     mynamespace.singleton = {};
     创建一个定义之后立即执行的函数创建单体:
      mynamespace.singleton = function{
       return{};
      }(); 

      类的作用和分析:
       1.第二个例子中并没有把一个函数复制给mynamespace.singleton。
       2.匿名函数返回类一个对象,而赋给mynamespace.singletion变量的正是这个对象。
       3.为了理解执行这个匿名函数,只需在其定义的最后那个大括号后面放上一堆圆括号即可。

  5.4.3两种技术的比较
   看dataparser例子,看看如何在其实现中使用真正的私有成员,不在是通过下划线为每个私有方法。
   giantcorp.dataparser = (function(){

    //私有属性
    var while = /\s+/;

    //私有方法
    function stripwhitespace(str){
     return str.replace(while,'');
    }

    function stringsplit(str,delimiter){
     return str.split(delimiter);
    }

    return {
     stringtoarray:function(str,delimiter,stripws){
      if(stripws){
       str = stripwhitespace(str);
      }
     }
     var outputArray = stringSplit(str,delimiter);
     retrun outputArray;

    }
   })();


   类分析:
    1.现在这些私有方法和属性可以直接用其名称访问,不必在其前面加上“this.”或“dataparser.” 这些前缀只用于访问单体对象的公有成员。
    这个模式与使用下划线表示法的模式比较的几点优势
     1.把私有成员放到闭包中可以确保其不会在单体对象之外被使用。
     2.可以自由的改变对象的实现细节。不会殃及别人的代码。
     3.这种方法对数据进行保护和封装。

   单体模式带来的好处:
    1.在使用这种模式时,你可以享受到真正的私有成员带来的所有好处。
    2.单体类只会被实例化一次。
    3.单体模式是javascript种最流行、应有最广泛的模式之一。

  5.5惰性实例化:
   前面所讲的单体模式的各种方法实现方式有一个共同点:
    1.单体对象都是在脚本加载时被创建出来
    2.对于资源密集型的或配置开销甚大的单体,在需要用到的才创建对象。这个技术被称为懒惰加载。
    3.作为命名空间。特定网页专用的代码包装器或者组织相关实用的方法还是立即加载。
    4.懒惰加载单体的特别之处。访问他们必须借助于一个静态。
    调用方式:Singleton.geninstance().methodname()而不是这样调用:singleton.methodname().
    5.getinstace方法会检查该单体是否已经被实例化。如果没有。那么它将创建并返回其实例。已经实例化就会返回现在的实例。

    6. 把普通的单体转化为惰性加载单体:
     mynamespace.singleton = (function(){
      var privateAttribute1 = false;
      var privateAttribute2 = [1,2,3];
      function privateMethod1(){

      }
      function privateMethod2(args){
      
      }

      return {
       publicAttribute1 : true,
       publicAttribute2 : 10,
       publicMethod1 : function(){

       },
       publicMethod2 : function(){

       }
      }
     })()

     转化第一步:把单体的所有代码移到一个名为constructor方法中:
      mynamespace.singleton = (function(){

       function constructor(){

         var privateAttribute1 = false;
         var privateAttribute2 = [1,2,3];
         function privateMethod1(){

         }
         function privateMethod2(args){
         
         }
         return {
           publicAttribute1 : true,
           publicAttribute2 : 10,
           publicMethod1 : function(){

           },
           publicMethod2 : function(){

           }
          }
       }


      })()

      类分析:
       1. 这个方法不能从闭包外部访问,所以我们可以全权控制器调用时机。
       2.公有方法getInstances是用来控制实现这种控制。
       3.getInstace要变成公有方法,需要放到一个对象字面量返回对象即可;

       examples:
        mynamaespace.singleton = (function(){

         function constructor (){

         }

         return {
          getinstace:{

          }
         }
        })()


        编写用于控制单体类的实例化时机的代码,需要中两件事:
         1.必须知道该类是否被实例化过。
         2.如果该类已经被实例化过。那么他需要掌握其实力的情况,以便能返回这个实例
         3.办这两件事需要用一个私有属性的已有的私有方法constructor

         mynamespace.singleton = (function(){
          var uniqueInstace;
          function constructor(){}
          return {
           getInstace : function(){
            if(uniqueinstace){
             uniqueInstace = constructor(); 
            }
            return uniqueInstace;
           }
          }
         })()

         调用方式:mynamespace.singleton.getinstace().publicmethod1();

         命名空间太长简化分: var mns = mynamespace.singleton;

   5.6分支

   5.8单体模式的适应场合
    1。从未代码的提供命名空间和增强模块的角度来说,应该尽量多使用单体模式。
    2.

 

 


 

© 著作权归作者所有

Q_z

Q_z

粉丝 18
博文 17
码字总数 14466
作品 0
成都
程序员
私信 提问
加载中

评论(1)

maosi
maosi
1.错别字:"第五张"
2.之前竟然没听说过"单体"这种说法,只知道"单例",查了下还真有叫"单体"的
《JavaScript设计模式与开发实践》原则篇(2)—— 最少知识原则

最少知识原则(LKP)说的是一个软件实体应当尽可能少地与其他实体发生相互作用。这 里的软件实体是一个广义的概念,不仅包括对象,还包括系统、类、模块、函数、变量等。 单一职责原则指导我们...

嗨呀豆豆呢
2018/12/30
0
0
《JavaScript设计模式与开发实践》最全知识点汇总大全

系列文章: 《JavaScript设计模式与开发实践》基础篇(1)—— this、call 和 apply 《JavaScript设计模式与开发实践》基础篇(2)—— 闭包和高阶函数 《JavaScript设计模式与开发实践》模式...

嗨呀豆豆呢
01/04
0
0
JavaScript设计模式总结

之前看过《JavaScript设计模式与开发实践》这本书,对书中的设计模式和一些相关案例也有了一定的了解,同时把这些设计模式的应用对应在在一些其他的项目中,进行了一些整理,如下仅供参考: ...

jefferyE
03/26
0
0
《JavaScript设计模式与开发实践》模式篇(12)—— 装饰者模式

在传统的面向对象语言中,给对象添加功能常常使用继承的方式,但是继承的方式并不灵活, 还会带来许多问题:一方面会导致超类和子类之间存在强耦合性,当超类改变时,子类也会随之 改变;另一方...

嗨呀豆豆呢
2018/12/25
0
0
JavaScript 中常见设计模式-单例模式

     单例模式两个条件   确保只有一个实例   可以全局访问   适用   适用于弹框的实现,全局缓存   实现单例模式      JavaScript 中的单例模式   因为 JavaScript 是无...

webstack前端栈
2018/05/19
0
0

没有更多内容

加载失败,请刷新页面

加载更多

Tedis:基于 TiKV 构建的 NoSQL 数据库

作者介绍: 陈东明,饿了么北京技术中心架构组负责人,负责饿了么的产品线架构设计以及饿了么基础架构研发工作。曾任百度架构师,负责百度即时通讯产品的架构设计。具有丰富的大规模系统构 ...

TiDB
16分钟前
0
0
linux命令

ls命令是linux下最常用的命令。ls命令就是list的缩写,缺省下ls用来打印出当前目录的清单。如果ls指定其他目录,那么就会显示指定目录里的文件及文件夹清单。 通过ls 命令不仅可以查看linux文件...

WinkJie
23分钟前
0
0
你需要的物流运输类报表,这里都有

你需要的物流运输类报表,都在这里 葡萄城报表模板库是一款免费的报表制作、学习和参考工具,包含了超过 200 张高质量报表模板,涵盖了 16 大行业和 50 多种报表类型,为 30 余万报表开发者提...

葡萄城技术团队
30分钟前
1
0
像Java SE一样编写Java EE(ddd探索)

今天主要改写昨天的组合模式成Web系统。 容器接口为 public interface TreeProduct { /** * 展示所有产品 * @return */ List<TreeProduct> allProducts();...

算法之名
32分钟前
0
0
Django Model 模型建立

Django Model 模型 Django Model层是Django的数据模型层,每一个Model类就是数据库中的一张表; 我们需要注意下面几点: model一般都是定义在不同的APP的models.py模块文件中,可以是一个,也...

彩色泡泡糖
40分钟前
3
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部