Singleton模式的类的实例创建依靠私有的构造函数和静态的创建函数
怎么销毁已经创建的单例实例呢?

解决方案 »

  1.   

    Singleton模式 
      

  2.   

    在你的构造函数里面改为实例不等于null就销毁
    实例等于null就create一个
      

  3.   

    实现IDispose,不使用的时候调用Dispose。
    例如
    public class DisposeableSingleton : IDisposable
    {
        //私有构造函数
        private DisposeableSingleton() { }
        //析构函数,避免最终都没有执行Dispose
        public ~DisposeableSingleton() { this.Dispose(); }
        //做你释放工作,注意用变量区分是否释放过避免重复释放
        public void Dispose() 
        {
            _instance = null;//复位静态对象,下次再用重新申请
        }
        private static DisposeableSingleton _instance = null;
        public static DisposeableSingleton Instance
        {
            get
            {
                return _instance == null ? new DisposeableSingleton() : _instance;
            }
        }
    }
      

  4.   

    使用:DisposeableSingleton.Instance
    释放:DisposeableSingleton.Instance.Dispose();
    当下次再用:goto line1自己看
      

  5.   

    囧,回头看看,写错一行。
    return _instance == null ? new DisposeableSingleton() : _instance;//->_instance = _instance == null ? new DisposeableSingleton() : _instance;
    return _instance;
      

  6.   


    class Singleton
    {
    public:
        static Singleton &Instance(){
            if( !m_pInstatnce){
                Lock(m_mutex);
                if( !m_pInstance ){
                    if(m_destroyed)
                        OnDeadReference();
                    else
                        Create();
                }
                UnLock(m_mutex);
            }
            return *m_pInstance;
        }
    private:
        static volatitle Singleton *m_pInstatnce;
        static bool m_destroyed;private:
        Singleton();
        Singleton(const Singleton&);
        Singleton& operator=(const Singleton&);
        ~Singleton(){
            m_pInstance = 0;
            m_destroyed = true;
        }    static void Create(){
            static Singleton sInstance;
            m_pInstanace = &sInstance;
        }    static void OnDeadReference(){
            Create();
            new (m_pInstance) Singleton;
            atexit(KillPhoenixSingleton);
            m_destroyed = false;
        }    void KillPhoenixSingleton(){
            m_pInstance->~Singleton();
        }
    }Singleton *Singleton:m_pInstatnce = NULL;
    bool m_destroyed = false;
      

  7.   


    C#的析构函数是什么时候执行的?还有IDisposable接口如果不是用using块,又怎么知道clr在什么时候调用?
      

  8.   

    c#的析构函数是在垃圾回收时执行的。我这么写的意思是如果你用到非托管资源,在你没有调用Dispose的情况下,在软件正常退出的最后一刻,垃圾回收要回收静态变量的,此时会调用析构函数进而调用Dispose释放非托管资源。using这种垃圾写法不过是微软自己拍脑袋瞎编的。没必要理会。你要的就是单例模式的类如何释放,那就不需要用的时候手工调用Dispose。如果一直不想释放,那就不调用呗。看你实际需要,一般单例模式都不需要释放的,一定要释放的话,就用我给你贴的那个做例子没问题。其实单例模式,如果提供Dispose的确是个不错的想法,比如单例模式操作某个硬件,硬件资源应当是独占的,当你长时间不用的时候,最好释放掉,一个是省电,一个是其他程序可以使用,当你再次需要的时候,调用Instance再次请求,但不论何时,总存在一个对象,这就是单例模式,算是一个特定环境的改进方案。
      

  9.   


    单列模式,Instance是私有的吧,只能用工厂来创建
      

  10.   


    我用单列就是想要一个单一实例的静态类,在应用程序启动时候创建,并且只执行一次创建过程,在程序结束的时候显式地释放单例类占用的资源,是不是在程序退出后,CLR在回收资源时执行析构函数?
    还有为什么说using是垃圾写法?我觉得是很好体现接口作用的写法
      

  11.   


    先不管用不用工厂,Instance是私有属性吧,不通过一个静态函数怎么访问?
      

  12.   


    单例模式就是用来保证对象唯一的。
    工厂模式是用来创建对象的,根据某些条件创建一个对象,如果现实中一个工厂只生产一种物品,而且只能生产一件,这个工厂还有什么意义呢?当然,设计模式只是常用的面向对象写法的一个总结。你完全可以依照自己的需要修改。比如你的单例对象需要多个条件来创建,你完全可以提供函数重载或单独提供一个构造方法。
    public class DisposeableSingleton : IDisposable
    {
        private int innerData = 0;
        //私有构造函数
        private DisposeableSingleton(int n) { }
        //析构函数,避免最终都没有执行Dispose
        ~DisposeableSingleton() { this.Dispose(); }
        //做你释放工作,注意用变量区分是否释放过避免重复释放
        public void Dispose()
        {
            _instance = null;//复位静态对象,下次再用重新申请
        }
        private static DisposeableSingleton _instance = null;
        //属性只负责返回对象不检查是否为null
        public static DisposeableSingleton Instance
        {
            get
            {
                return _instance;
            }
        }
        //使用参数构造对象
        public void CreateInstance(int i)
        {
            _instance = _instance == null ? new DisposeableSingleton(i) : _instance;
        }
    }
      

  13.   

    Instance就是你单例模式的唯一调用方法,Instance私有了如何访问你的对象?
      

  14.   

    c++中没有属性,所以c++描述的设计模式书上会写GetInstance()方法来获得对象的指针或引用。c#/java都是有属性的。你依然可以写GetInstance(),当然也可以用属性Instance。
      

  15.   


    你的意思Instance是一个方法?对不起,我理解成属性了,不过方法的名称一般都是动词+宾语的写法吧我现在用的就是这个方法,但是我觉得不完美
        public class WorkflowRuntimeManager
        {
            /// <summary>
            /// 单例模式的实例
            /// </summary>
            private static WorkflowRuntimeManager _instance = null;        public WorkflowRuntime wfRuntime { get; protected set; }        ///// <summary>
            ///// 装饰器
            ///// </summary>
            //private WorkflowRuntime _wfRuntime = null;        /// <summary>
            /// 私有的构造函数
            /// </summary>
            protected WorkflowRuntimeManager()
            {
                //创建实例
                wfRuntime = new WorkflowRuntime();            //添加核心服务
                ExternalDataExchangeService exchangeService = new ExternalDataExchangeService();
                wfRuntime.AddService(exchangeService);        }        /// <summary>
            /// 返回WorkflowRuntimeManager的单例实例,如果实例不存在,创建实例
            /// </summary>
            /// <returns></returns>
            public static WorkflowRuntimeManager getInstance()
            {
                if (_instance == null)
                {
                    _instance = new WorkflowRuntimeManager();
                }
                return _instance;
            }
            public void AddSqlPersistenceService(string connectionString)
            {
                if (wfRuntime.IsStarted)
                {
                    throw new ApplicationException("工作流运行时已经启动,无法添加核心服务!请在运行时启动前运行此方法!");
                }
                else
                {
                    WorkflowPersistenceService persistenceService = new SqlWorkflowPersistenceService(connectionString);
                    wfRuntime.AddService(persistenceService);
                }
            }        public void StartWfRuntime()
            {
                if (!wfRuntime.IsStarted)
                {
                    wfRuntime.StartRuntime();
                }
            }        public void StopWfRuntime()
            {
                if (wfRuntime.IsStarted)
                {
                    wfRuntime.StopRuntime();
                }        }        public void DestroyInstance()
            {
                if (_instance != null)
                {
                    StopWfRuntime();
                    wfRuntime.Dispose();
                    _instance = null;
                }
            }    }
      

  16.   

    你说要弄个工厂,我说工厂没必要。才给你写个单独的构造方法的。而即便按24楼的写法,依然可以保证所有使用Instance的地方访问的是同一个对象。单例的意义就是共享访问。本来就没固定的实现方式。就公开一个静态变量也是一种实现方式。实现方式是最终的代码,设计模式是表示设计思路和方法。而你的问题前后一共2个:
    1。Singleton模式的类的实例创建依靠私有的构造函数和静态的创建函数
    怎么销毁已经创建的单例实例呢?
    2。使用工厂创建单例对象对于问题1.已经给你实现和解释了。如果认为不合理,我没看到你针对性的回复。
    问题2,我写这么多就是想说,工厂模式和单例模式两个模式,没必然联系。而如果单例的对象本身没有无参构造函数,那提供一个构造器是有必要的,但这不影响其唯一性。
      

  17.   

    接28#
    销毁类时候用WorkflowRuntimeManager.getInstance().DestroyInstance();问题来了,如果已经销毁了,调用静态方法getInstance(),会先创建对象,再销毁对象,还有什么更好的办法?
      

  18.   

    怎么写都没问题。自己看着舒服,不出错就可以了。没必要硬套到模式中。你误解我给你回复多次了。--------------
    你的意思Instance是一个方法?对不起,我理解成属性了,不过方法的名称一般都是动词+宾语的写法吧
    --------------是属性Property。我说:Instance就是你单例模式的唯一调用方法,Instance私有了如何访问你的对象?
    这个调用方法你理解错了。这个方法我是想说:途径。你写的没问题。挺好。不过工厂返回一个产品的单例是比较怪的写法。我没做过web,不知道是不是都这么写的。
      

  19.   


    工厂的事先不谈,因为和主题其实没多大关系
    至于你说的用IDispose接口,说明你对IDispose的作用不理解,这里没有必要用IDispose接口,因为没有任何机会供CLR调用dispose函数,只要写一个销毁函数就行了,但是我的疑问请看#31的回复
      

  20.   


    如果你尚未使用就要释放,那的确是你说的这个过程。
    或是再写个静态的
    public static void DisposeMute()
    {
        if(_instance!=null)_instance.Dispose();
    }
      

  21.   


    知道了,这个属性的作用,应该和我getInstance()方法是一样的,问题看31楼
      

  22.   


    这个是行不通的,我早试过了,静态函数里面不能访问_instance的Dispose()函数
      

  23.   


    好,我不理解。你理解。那你不实现IDispose接口就可以了。
    IDispose接口的意义在于告诉垃圾回收器,实现此接口的类需要手工的释放非托管资源,只是一个约定。你完全可以不按照约定来做,没任何问题。
      

  24.   


    说明你当时试错了。
    你没实现IDispose接口,又写了Dispose方法,跟在哪里调用没关系。访问的是静态变量_instance的成员方法,仅此而已。