Singleton模式

来自KlniuWiki
跳转到: 导航, 搜索

目录

1 问题

个人认为Singleton模式是设计模式中最为简单、最为常见、最容易实现,也是最应该熟悉和掌握的模式。且不说公司企业在招聘的时候为了考察员工对设计的了解和把握,考的最多的就是Singleton模式。

Singleton模式解决问题十分常见,我们怎样去创建一个唯一的变量(对象)?在基于对象的设计中我们可以通过创建一个全局变量(对象)来实现,在面向对象和面向过程结合的设计范式(如C++中)中,我们也还是可以通过一个全局变量实现这一点。但是当我们遇到了纯粹的面向对象范式中,这一点可能就只能是通过Singleton模式来实现了,可能这也正是很多公司在招聘Java开发人员时候经常考察Singleton模式的缘故吧。

2 功能

保证一个类仅有一个实例。

3 结构图

singleton_pattern01.gif

4 优缺点

Singleton模式是做为"全局变量"的替代品出现的。所以它具有全局变量的特点:全局可见、贯穿应用程序的整个生命期,它也具有全局变量不具备的性质:同类型的对象实例只可能有一个。

5 实现

教科书上的Singleton定义如下:

class Singleton
{
    public:
        static Singleton* Instance() ;
    protected:
        Singleton() {}
    private:
        static Singleton *_instance ;
        Singleton(const Singleton&) ;
        Singleton& operator=(const Singleton&) ;
} ;
 
Singleton* Singleton::_instance = NULL ;
 
Singleton* Singleton::Instance()
{
    (_instance == NULL) ? _instance = new Singleton() : 0 ; //lazy initialization
    return _instance ;
}
  1. 因为返回的是指针,为防止用户调用delete函数,可把static Singleton *_instance;改为在Instance()中定义static Singleton _instance。这样显然更安全,同时也具有lazy initialization的特性(即第一次访问时才创建)。
  2. 假设需要从Singleton派生子类,而子类也需要有同样的性质,既只能创建一个实例。我觉得,这很难办。根本原因在于Instance() 函数不是虚函数,不具有多态的性质。一种常用方法是把Instance()函数移到子类中,这时就只能用static Singleton *_instance,而不能用static Singleton _instance了,除非把_instance也要移到子类,无论怎么做都不优雅。另一种方法是用模板。具体用什么方法,只能根据实际情况权衡。

6 示例代码

  • 没子类的情况
namespace DesignPattern_Singleton
{
 
    class Singleton
    {
        public:
            static Singleton* Instance() { static Singleton _instance ; return &_instance ; }
        protected:
            Singleton() {}
        private:
            Singleton(const Singleton&) ;
            Singleton& operator=(const Singleton&) ;
    } ;
}
客户端代码:
{
    using namespace DesignPattern_Singleton ;
    Singleton *p = Singleton::Instance() ;
    ......
}
  • 有子类的情况
方法一:
namespace DesignPattern_Singleton
{
    // class Singleton
    class Singleton
    {
        protected:
            Singleton() {}
            static Singleton *_instance ;
        private:
            Singleton(const Singleton&) ;
            Singleton& operator=(const Singleton&) ;
    } ;
    Singleton* Singleton::_instance = NULL ;
 
    // class ConcreteSingleton
    class ConcreteSingleton : public Singleton
    {
        public:
            static Singleton* Instance() ;
        protected:
            ConcreteSingleton() {}
    } ;
 
    Singleton* ConcreteSingleton::Instance()
    {
        (_instance == NULL) ? _instance = new ConcreteSingleton() : 0 ; 
        return _instance ;
    }
}
客户端代码:
{
    using namespace DesignPattern_Singleton ;
    Singleton *p = ConcreteSingleton::Instance() ;
}
方法二:
namespace DesignPattern_Singleton
{
    // class Singleton
    class Singleton
    {
        protected:
            Singleton() {}
        private:
            Singleton(const Singleton&) ;
            Singleton& operator=(const Singleton&) ;
    } ;
 
    // class ConcreteSingleton
    class ConcreteSingleton : public Singleton
    {
        public:
            static Singleton* Instance() { static ConcreteSingleton _instance ; return &_instance ; }
        protected:
            ConcreteSingleton() {}
    } ;
}
客户端代码:
{
    using namespace DesignPattern_Singleton ;
    Singleton *p = ConcreteSingleton::Instance() ;
}
方法三:
namespace DesignPattern_Singleton
{
    template < class T >
        class Singleton
        {
            public:
                static T* Instance() { static T _instance ; return &_instance ; }
            protected:
                Singleton() {}
            private:
                Singleton(const Singleton &) ;
                Singleton& operator=(const Singleton&) ;
        } ;
 
    class ConcreteSingleton : public Singleton< ConcreteSingleton > {} ;
}
客户端代码:
{
    using namespace DesignPattern_Singleton ;
    ConcreteSingleton *p = ConcreteSingleton::Instance() ;
}

7 讨论

Singleton模式在开发中经常用到,且不说我们开发过程中一些变量必须是唯一的,比如说打印机的实例等等。

Singleton模式经常和Factory(AbstractFactory)模式在一起使用,因为系统中工厂对象一般来说只要一个,笔者在开发Visual CMCS的时候,语义分析过程(以及其他过程)中都用到工厂模式来创建对象(对象实在是太多了),这里的工厂对象实现就是同时是一个Singleton模式的实例,因为系统我们就只要一个工厂来创建对象就可以了。

8 参见

个人工具
分类
化学
[×] 國學
学佛
[×] 数学
物理
生活
[×] 英语
读书
辞典
廣告