Singleton模式的类能不能销毁呢?

Ricercar 2010-08-19 05:58:04
Singleton模式的类的实例创建依靠私有的构造函数和静态的创建函数
怎么销毁已经创建的单例实例呢?
...全文
325 43 打赏 收藏 转发到动态 举报
写回复
用AI写文章
43 条回复
切换为时间正序
请发表友善的回复…
发表回复
Ricercar 2010-08-20
  • 打赏
  • 举报
回复
工厂的确没必要,这么些看上去好看一点而已
Ricercar 2010-08-20
  • 打赏
  • 举报
回复
[Quote=引用 24 楼 wuyazhe 的回复:]

单例模式就是用来保证对象唯一的。
工厂模式是用来创建对象的,根据某些条件创建一个对象,如果现实中一个工厂只生产一种物品,而且只能生产一件,这个工厂还有什么意义呢?

当然,设计模式只是常用的面向对象写法的一个总结。你完全可以依照自己的需要修改。比如你的单例对象需要多个条件来创建,你完全可以提供函数重载或单独提供一个构造方法
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;
}
}

[/Quote]

这个还是不理解,如果参数化构造单例实例?
Ricercar 2010-08-20
  • 打赏
  • 举报
回复
[Quote=引用 40 楼 wuyazhe 的回复:]

引用 36 楼 ricercar 的回复:
这个是行不通的,我早试过了,静态函数里面不能访问_instance的Dispose()函数


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

可以了,是我搞错了
兔子-顾问 2010-08-20
  • 打赏
  • 举报
回复
[Quote=引用 36 楼 ricercar 的回复:]
这个是行不通的,我早试过了,静态函数里面不能访问_instance的Dispose()函数
[/Quote]

说明你当时试错了。
你没实现IDispose接口,又写了Dispose方法,跟在哪里调用没关系。访问的是静态变量_instance的成员方法,仅此而已。
SK_Aqi 2010-08-20
  • 打赏
  • 举报
回复
学习a
aolongxue 2010-08-20
  • 打赏
  • 举报
回复
单例模式很复杂,很强大
兔子-顾问 2010-08-20
  • 打赏
  • 举报
回复
[Quote=引用 33 楼 ricercar 的回复:]
工厂的事先不谈,因为和主题其实没多大关系
至于你说的用IDispose接口,说明你对IDispose的作用不理解,这里没有必要用IDispose接口,因为没有任何机会供CLR调用dispose函数,只要写一个销毁函数就行了,但是我的疑问请看#31的回复
[/Quote]

好,我不理解。你理解。那你不实现IDispose接口就可以了。


IDispose接口的意义在于告诉垃圾回收器,实现此接口的类需要手工的释放非托管资源,只是一个约定。你完全可以不按照约定来做,没任何问题。
Ricercar 2010-08-20
  • 打赏
  • 举报
回复
[Quote=引用 34 楼 wuyazhe 的回复:]

引用 31 楼 ricercar 的回复:
接28#
销毁类时候用WorkflowRuntimeManager.getInstance().DestroyInstance();

问题来了,如果已经销毁了,调用静态方法getInstance(),会先创建对象,再销毁对象,还有什么更好的办法?


如果你尚未使用就要释放,那的确是你说的这个过程。
或是再写个静态的
public ……
[/Quote]

这个是行不通的,我早试过了,静态函数里面不能访问_instance的Dispose()函数
Ricercar 2010-08-20
  • 打赏
  • 举报
回复
[Quote=引用 32 楼 wuyazhe 的回复:]

怎么写都没问题。自己看着舒服,不出错就可以了。没必要硬套到模式中。你误解我给你回复多次了。

--------------
你的意思Instance是一个方法?对不起,我理解成属性了,不过方法的名称一般都是动词+宾语的写法吧
--------------

是属性Property。

我说:Instance就是你单例模式的唯一调用方法,Instance私有了如何访问你的对象?
……
[/Quote]

知道了,这个属性的作用,应该和我getInstance()方法是一样的,问题看31楼
兔子-顾问 2010-08-20
  • 打赏
  • 举报
回复
[Quote=引用 31 楼 ricercar 的回复:]
接28#
销毁类时候用WorkflowRuntimeManager.getInstance().DestroyInstance();

问题来了,如果已经销毁了,调用静态方法getInstance(),会先创建对象,再销毁对象,还有什么更好的办法?
[/Quote]

如果你尚未使用就要释放,那的确是你说的这个过程。
或是再写个静态的
public static void DisposeMute()
{
if(_instance!=null)_instance.Dispose();
}
Ricercar 2010-08-20
  • 打赏
  • 举报
回复
[Quote=引用 30 楼 wuyazhe 的回复:]

你说要弄个工厂,我说工厂没必要。才给你写个单独的构造方法的。而即便按24楼的写法,依然可以保证所有使用Instance的地方访问的是同一个对象。单例的意义就是共享访问。本来就没固定的实现方式。就公开一个静态变量也是一种实现方式。实现方式是最终的代码,设计模式是表示设计思路和方法。

而你的问题前后一共2个:
1。Singleton模式的类的实例创建依靠私有的构造函数和静态的创建函数
怎么……
[/Quote]

工厂的事先不谈,因为和主题其实没多大关系
至于你说的用IDispose接口,说明你对IDispose的作用不理解,这里没有必要用IDispose接口,因为没有任何机会供CLR调用dispose函数,只要写一个销毁函数就行了,但是我的疑问请看#31的回复
兔子-顾问 2010-08-20
  • 打赏
  • 举报
回复
怎么写都没问题。自己看着舒服,不出错就可以了。没必要硬套到模式中。你误解我给你回复多次了。

--------------
你的意思Instance是一个方法?对不起,我理解成属性了,不过方法的名称一般都是动词+宾语的写法吧
--------------

是属性Property。

我说:Instance就是你单例模式的唯一调用方法,Instance私有了如何访问你的对象?
这个调用方法你理解错了。这个方法我是想说:途径。

你写的没问题。挺好。不过工厂返回一个产品的单例是比较怪的写法。我没做过web,不知道是不是都这么写的。
Ricercar 2010-08-20
  • 打赏
  • 举报
回复
接28#
销毁类时候用WorkflowRuntimeManager.getInstance().DestroyInstance();

问题来了,如果已经销毁了,调用静态方法getInstance(),会先创建对象,再销毁对象,还有什么更好的办法?
兔子-顾问 2010-08-20
  • 打赏
  • 举报
回复
你说要弄个工厂,我说工厂没必要。才给你写个单独的构造方法的。而即便按24楼的写法,依然可以保证所有使用Instance的地方访问的是同一个对象。单例的意义就是共享访问。本来就没固定的实现方式。就公开一个静态变量也是一种实现方式。实现方式是最终的代码,设计模式是表示设计思路和方法。

而你的问题前后一共2个:
1。Singleton模式的类的实例创建依靠私有的构造函数和静态的创建函数
怎么销毁已经创建的单例实例呢?
2。使用工厂创建单例对象

对于问题1.已经给你实现和解释了。如果认为不合理,我没看到你针对性的回复。
问题2,我写这么多就是想说,工厂模式和单例模式两个模式,没必然联系。而如果单例的对象本身没有无参构造函数,那提供一个构造器是有必要的,但这不影响其唯一性。
Ricercar 2010-08-20
  • 打赏
  • 举报
回复
[Quote=引用 26 楼 wuyazhe 的回复:]

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

我说的属性不是某一样语言的具体实现方式(用属性还是变量),只是面向对象的一种概念
Ricercar 2010-08-20
  • 打赏
  • 举报
回复
[Quote=引用 25 楼 wuyazhe 的回复:]

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

你的意思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;
}
}

}

Ricercar 2010-08-20
  • 打赏
  • 举报
回复
[Quote=引用 24 楼 wuyazhe 的回复:]

引用 21 楼 ricercar 的回复:
我的意思是为了保证单一性,用一个工厂来创建


单例模式就是用来保证对象唯一的。
工厂模式是用来创建对象的,根据某些条件创建一个对象,如果现实中一个工厂只生产一种物品,而且只能生产一件,这个工厂还有什么意义呢?

当然,设计模式只是常用的面向对象写法的一个总结。你完全可以依照自己的需要修改。比如你的单例对象需要多个条件来创建,你完全可以提……
[/Quote]

不是我说什么,你也没理解单例模式,单例模式类怎么可能有多个构造方法?如果已经创建了实例,又怎么去根据条件来创建不同的单例?这种情况只能写几个不同的单例类来实现
兔子-顾问 2010-08-20
  • 打赏
  • 举报
回复
c++中没有属性,所以c++描述的设计模式书上会写GetInstance()方法来获得对象的指针或引用。c#/java都是有属性的。你依然可以写GetInstance(),当然也可以用属性Instance。
兔子-顾问 2010-08-20
  • 打赏
  • 举报
回复
Instance就是你单例模式的唯一调用方法,Instance私有了如何访问你的对象?
兔子-顾问 2010-08-20
  • 打赏
  • 举报
回复
[Quote=引用 21 楼 ricercar 的回复:]
我的意思是为了保证单一性,用一个工厂来创建
[/Quote]

单例模式就是用来保证对象唯一的。
工厂模式是用来创建对象的,根据某些条件创建一个对象,如果现实中一个工厂只生产一种物品,而且只能生产一件,这个工厂还有什么意义呢?

当然,设计模式只是常用的面向对象写法的一个总结。你完全可以依照自己的需要修改。比如你的单例对象需要多个条件来创建,你完全可以提供函数重载或单独提供一个构造方法。
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;
}
}
加载更多回复(23)

62,046

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术交流专区
javascript云原生 企业社区
社区管理员
  • ASP.NET
  • .Net开发者社区
  • R小R
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

.NET 社区是一个围绕开源 .NET 的开放、热情、创新、包容的技术社区。社区致力于为广大 .NET 爱好者提供一个良好的知识共享、协同互助的 .NET 技术交流环境。我们尊重不同意见,支持健康理性的辩论和互动,反对歧视和攻击。

希望和大家一起共同营造一个活跃、友好的社区氛围。

试试用AI创作助手写篇文章吧