bob体育官方平台
无标题文章

JS 单例模式

***单例模式

使用方法:
1.加入YUI.Ext 库到你的web程序: 

概要:

### 一、什么是单例模式

1、单例:保证一个类仅有一个实例,并提供一个访问它的全局访问点。

2、单例模式是一种常用的软件设计模式之一,其目的是保证整个应用中只存在类的唯一个实例。

比如我们在系统启动时,需要加载一些公共的配置信息,对整个应用程序的整个生命周期中都可见且唯一,这时需要设计成单例模式。如:spring容器,session工厂,缓存,数据库连接池,网络连接池等等。

### 二、如何保证实例的唯一

1、防止外部初始化

2、由类本身进行实例化

3、保证实例化一次

4、对外提供获取实例的方法

5、线程安全

<!-- YAHOO UI Utilities Lib, you will need to replace this with the path to your YUI lib file -->
<script type="text/javascript" src="deepcms/yui/utilities_2.1.0.js"></script><script type="text/javascript" src="deepcms/yui-ext.0.33-rc1/yui-ext.js"></script>
2.加入样式表 CSS Style 。如果你是一个美工,最多打交道的地方,可能就是这几个文件:
<!--YahooUI! Ext --> 
<link rel="stylesheet" type="text/css" href="yui-ext.0.33-rc1/resources/css/reset-min.css" /> 
<link rel="stylesheet" type="text/css" href="yui-ext.0.33-rc1/resources/css/resizable.css" />
<link rel="stylesheet" type="text/css" href="yui-ext.0.33-rc1/resources/css/tabs.css" /> 
<link rel="stylesheet" type="text/css" href="yui-ext.0.33-rc1/resources/css/basic-dialog.css" /> 

单例指一个类只有一个实例,这个类自行创建这个实例。

### 三、几种单利模式的实现和比较

1、饿汉模式

“因为饿,所以要立即吃饭,刻不容缓”,在定义类的静态私有变量同时进行实例化。

```java

public class Singleton {

private static final Singleton singleton = new Singleton();

private Singleton() {

}

public static Singleton getInstance() {

if (instance == null) {

instance = new Singleton();

}

return instance;

}

}

```

当然上面的饿汉模式中的对象,你也可以放在静态代码块中进行初始化

```java

public class Singleton {

private static  Singleton singleton = null;

static{

singleton = new Singleton()

}

private Singleton() {

}

public static Singleton getInstance() {

return singleton;

}

}

```

2、懒汉模式

“因为懒,所以都忘记了创建初始对象”,在定义类的静态私有变量,不进行初始化。

```java

public class Singleton {

private static Singleton instance;

private Singleton (){}

public static Singleton getInstance() {

if (instance == null) {

instance = new Singleton();

}

return instance;

}

}

```

3、如果使涉及到线程问题,上面的例子并不能满足您的要求了,因为线程不安全,那如何实现线程安全的单例模式呢,上代码(懒汉)

```java

public class Singleton {

private static Singleton instance;

private Singleton (){}

public static  Singleton getInstance() {

if (singleton == null) {  //  1号

synchronized (Singleton.class) {

if (singleton == null) {  //2号

singleton = new Singleton();

}

}

}

return singleton;

}

}

```

可能您会疑惑,为什么要判断两次空?举个例子,现在有两个线程A和B。假设A先执行,B后执行,此时同时运行到1号备注,此时的singleton ==  null。下一刻A继续运行,B等待,当A执行完成后singleton !=  null。所以当B执行的时候不需要再创建。所以需要两次判断。

4、静态内部类。优点:既避免了同步带来的性能损耗,又能够延迟加载

```java

public class Singleton {

private Singleton() {

}

private static class SingletonHolder {

private static final Singleton singleton = new Singleton();

}

public static Singleton getInstance() {

return SingletonHolder.singleton;

}

}

```

5、枚举。天然线程安全,可防止反射生成实例。

```java

public enum Singleton {

INSTANCE;

public void init() {

System.out.println("资源初始化。。。");

}

}

```

### 四、总结

优点:该类只存在一个实例,节省系统资源;对于需要频繁创建销毁的对象,使用单例模式可以提高系统性能。

缺点:不能外部实例化(new),调用人员不清楚调用哪个方法获取实例时会感到迷惑,尤其当看不到源代码时。

### 附录:后续将会推出一系列设计模式文章,请关注我的博客 [lueans](

3.加入一个holder.holder的意思是一个载体,JS处理好数据,转变成内容(Contents,文字、图片、表格等)放在这里,也可以理解为一个架子,承托所有内容。holder表现形式很简单,通常是几行div。 

利用对象字面量直接生成一个单例:

<div id="hello-dlg" style="visibility:hidden;position:absolute;top:0px;">    
 <div class="ydlg-hd">中易旅游网</div>    
 <div class="ydlg-bd"> 您没确认条款内容。</div>     
</div>
4.加入定义Dialog脚本,实例化Dialog:

var singleton = { prop: 1, method: function; //1 }}

// create the HelloWorld application (single instance)
var HelloWorld = function(){
    // everything in this space is private and only accessible in the HelloWorld block
    //任何在这个区域的都是私有变量 ,只能在HelloWorld访问
    var dialog, showBtn;

严格的说对象字面量可能不算单例模式,生成单例是对象字面量的作用,而单例模式是一个设计模式。

    var toggleTheme = function(){
        getEl(document.body, true).toggleClass('ytheme-gray');
    };
    // return a public interface
    return {
        init : function(){
             showBtn = getEl('goNextBtn'); //绑定一个按钮
             // attach to click event 加入事件
             /showBtn.on('click', this.showDialog, this, true);

在类内部用new生成实例的单例模式:

             ///getEl('theme-btn').on('click', toggleTheme);
        },

var instance;var foo = function{ instance = new Singleton(); } return instance; function Singleton(){ this.name = 'single'; this.method = function(){ console.log; } };} var a = foo;a.method(); //singleconsole.log; //true

        showDialog : function(){
            if(!dialog){ //因为采用单例模式,不能被new重复实例。这里是用懒惰的方法作判断。 
                dialog = new YAHOO.ext.BasicDialog("hello-dlg", { 
                        modal:true,//这段代码是dialog的一些参数,如大小、有冇阴影、是否覆盖select等
                        autoTabs:false,
                        width:180,
                        height:100,
                        shadow:true,
                        minWidth:508,
      shim: true,
      autoScroll: false,
      resizable:false,
                        minHeight:300
                });
                dialog.addKeyListener(27, dialog.hide, dialog);//键盘事件Esc退出
                dialog.addButton('退出', dialog.hide, dialog);
                         }
            dialog.show(showBtn.dom);//参数为动画效果出现的地方
        }
    };
}();//注意这对括号,如果没有将不会执行。
//用onDocumentReady代替windows.onload初始化程序。当DOM准备好,无须等待载入图片和其他资源;有关两者的讨论,请看这里
YAHOO.ext.EventManager.onDiocumentReady(HelloWorld.init, HelloWorld, true);
难点分析: Singleton Pattern 设计模式之单例 

单例模式只要检测一个实例是否被生成。假如没有实例,则生成实例。假如已经生成则返回这个实例。保证这个类只有这一个实例。

什么是 Singleton Pattern?

由于hoisting,函数会提前声明,所以 singleton 函数放在哪都没所谓,但是每次调用都会声明函数singleton,可能会不够优雅。

Anwser: 单例模式(Singleton Pattern)是一种非常基本和重要的创建型模式。 “单例”的职责是保证一个类有且只有一个实例,并提供一个访问它的全局访问点。 在程序设计过程中,有很多情况下需要确保一个类只能有一个实例。 

返回顶部