设计模式——单例模式(Singleton Pattern)

来源:互联网 发布:粉笔直播课 mac版 编辑:程序博客网 时间:2024/04/24 11:15


单例模式(Singleton) 


意图:确保一个类只有一个实例,并提供一个全局的访问点

问题描述:

校园网想必大家都用过吧!有的需要登录客户端才能正常的连接网络,现在就用这种登录客户端为例。一台电脑只需要一个账号就可以了,如果出现一台电脑同时登录两个账号或者更多(不同电脑同时登录的情况暂不考虑),不但浪费我们的费用,而且计费系统也会出现一些问题!如何避免这样的问题呢?我们可以限制打开登录窗口的个数为最多一个,这样在登录一个账号后,还要登录账号就会打开原先登录的账号窗口(或者提示客户端已打开等)阻止用户登录多次登录。如下图所示:当客户端打开之后,再打开就会提示程序已运行

                                           


怎样才能实现只有一个“客户端”实例呢?有两种方法:一、由程序员自己控制,在应用中使代码只有一个实例被创建。二、不依靠程序员,精心设计这个要使用的类,让它在程序全程中仅有一个实例被创建。显然第二种更有效,更安全,而第一种很容易出现错误导致创建多个实例!第二种方式就称为单例模式

解决方案:

如何实现单利模式呢?首先不能让类外直接通过 new 来任意的创建该类的对象,自己控制本身实例的产生,所以要将自己的构造函数私有化

public class Singleton{        private Singleton(){}}

单单这样还不能达到我们的要求,因为现在类只实现了构造函数的私有化。不过我们已经迈出了一大步,我们已经限制了对象的产生!如何让类自己控制产生对象就行了!有两种方法:(有很多种创建方式,此处只介绍两种)

一、当类创建时就创建自身对象,在外界需要时就通过静态方法直接返回已经创建好的对象。这种方式被叫做“饿汉式”。上代码:

public class Singleton {private static Singleton singleton = new Singleton();private Singleton(){}public static Singleton getInstance(){return singleton;}}

二、在静态方法中判断类的实例是否已经创建,如没有创建则创建对象并返回,否则直接返回已创建的对象。这种方式叫做“懒汉式

public class Singleton {private static Singleton singleton = null;private Singleton(){}public static Singleton getInstance(){if(singleton == null){singleton = new Singleton();}return singleton;}}


优缺点:

饿汉式单例类:

   缺点:会产生内存浪费,因为在加载Singleton类时就已经初始化共享对象实例;

    优点:多线程的程序中,多个线程同时访问Singleton类也不会造成多个实例,执行效率高


懒汉式单例类:

   优点:不会产生内存浪费,因为共享对象在调用getInstance()方法时才被创建的;

    缺点:多线程的程序中,多个线程同时访问Singleton类,调用getInstance()方法,可能造成多个实例。


懒汉式线程安全问题的解决方法:

加上线程锁:

public class Singleton {private static Singleton singleton = null;private Singleton(){}public static synchronized Singleton getInstance(){if(singleton == null){singleton = new Singleton();}return singleton;}}

双重检查:

public class Singleton {private static Singleton singleton = null;private Singleton() {}public static Singleton getInstance(){if(singleton == null){synchronized (Singleton.class){if(singleton == null){singleton = new Singleton();}}}return singleton;}}



实际体会:

    例如:在cocos2d-x中,经常将一些常用类(例如:CCDirector)设计为单例模式,好处是可以随时随地调用你所需要类的唯一实例。这就好比把他们变成了全局变量,任何时候都可以随意调用。

0 0
原创粉丝点击