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

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

单体对象的区分;
  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.

时间: 2024-10-13 16:17:26

javascript设计模式第5张--单体设计模式的相关文章

浅谈javascript单体【读javascript设计模式第五章节单体有感】

单体,整个运行环境就独有一份,最简单的一种单体就是一个把所有属性和方法都集中在一起的对象,区别于一般的字面量对象,一般字面量对象是对一个物体的描述,集合该物体所具有的一些属性和方法,而单体则包含更多的些逻辑在里面,单体的好处有,划分命名空间,如果用来作为网页包装器,可以使得页面所有变量都封装在一个对象里,大幅度减小网页里的全局变量, 代码如: common.js (function(wz){ $.extend({ init:function(){ var self = this; this.bi

Asp.net设计模式笔记之一:理解设计模式

GOF设计模式著作中的23种设计模式可以分成三组:创建型(Creational),结构型(Structural),行为型(Behavioral).下面来做详细的剖析. 创建型 创建型模式处理对象构造和引用.他们将对象实例的实例化责任从客户代码中抽象出来,从而让代码保持松散耦合,将创建复杂对象的责任放在一个地方,这遵循了单一责任原则和分离关注点原则. 下面是“创建型”分组中的模式: 1.Abstract Factory(抽象工厂)模式:提供一个接口来创建一组相关的对象. 2.Factory Met

设计模式小计——23种设计模式3

责任链模式Chain of Responsibility 使多个对象都有机会处理请求,从而避免请求的发送者和接受者间的耦合关系,并沿着这条链传递请求,直到有对象处理它为止 责任链模式关键是建立链接关系,在链中决定谁来处理请求 //抽象处理者 public abstract class Handle{ private Handle nextHandle;//链的下一个节点 public final Response handleMessage(Request request){ Response

设计模式小计——23种设计模式1

单例模式Singleton Pattern 确保类只有一个实例,而且自行实例化并向整个系统提供这个实例 public class Singleton{ private static final Singleton singleton = new Singleton(); private Singleton(){} public static Singleton getSingleton(){ return singleton; } } 节省内存开支,减少性能开销,应用启动产生单例对象,永久驻留内

设计模式小计——23种设计模式2

模板方法模式Template Method Pattern 定义一个操作的算法的框架,是的子类可以不改变算法结构即可重定义该算法一些特定步骤 public abstract class AbstractClass{//抽象模板类 protected abstract void method1();//算法步骤1 protected abstract void method2();//算法步骤2 public void templateMethod(){//模板方法,定义算法结构 this.met

每天一个设计模式(0):设计模式概述

本系列是基于阅读<Head First 设计模式>而产生的,也算是此书的阅读笔记. 由于目前事情比较多,本系列内容参考了几个大神的博客内容.以后时间充裕了,或对某种模式有了更深入的理解后,会及时更新对应文章. 参考的几个大神的博客主页如下:http://www.cnblogs.com/mengdd/ http://blog.csdn.net/zhangerqing?viewmode=contents 设计模式 设计模式(Design pattern)是一套被反复使用.多数人知晓的.经过分类编目

易学设计模式看书笔记(1) - 设计模式的分类

1 创建型模式 单独对对象的创建进行研究,高效的创建对象就是创建型模式讨论的问题.创建型设计模式有6种: 简单工厂模式(simple factory): 工厂方法模式(factory method): 抽象工厂模式(abstract factory): 创建者模式(Builder): 原型模式(Prototype): 单例模式(Singleton). 2 结构型模式 在解决了对象的创建问题之后,对象的组成以及对象之间的依赖关系就成了关注的焦点,因为如何设计对象之间的结构.继承和依赖关系会影响到后

JAVA设计模式总结之23种设计模式

一.什么是设计模式                                                                                                                                        设计模式(Design pattern)是一套被反复使用.多数人知晓的.经过分类编目的.代码设计经验的总结.使用设计模式是为了可重用代码.让代码更容易被他人理解.保证代码可靠性. 毫无疑问,设计模式于己于他人于

关于W3Cschool定义的设计模式--常用的9种设计模式的介绍

一.设计模式 tip:每种设计模式,其实都是为了更高效的,更方便的解决在面对对象编程中所遇到的问题. 什么是设计模式: 是一套经过反复使用.多人知晓的.经过分类的.代码设计经验的总结 为什么使用设计模式: 为了代码的可重用性.让代码更容易被他人理解.保证代码的可靠性.设计模式使代码的编写真正的工程化:设计模式是软件工程的基石脉络,如同大厦的结构. 有哪些设计模式(来自W3Cschool,23种): 构造器模式,模块化模式,暴露模块模式,单例模式,中介者模式,原型模式,命令模式,外观模式,工厂模式