浏览:11462007-11-20 15:48   来自彭成刚      :

单件模式,是啥,从字面上也看的出来吧,就是实体唯一。还有啥好的?应该属于推迟实例化吧。。

下面来看看官方是咋说的:单件模式确保一个类只有一个实例,并提供一个全局访问点。

就我看来,这斯的功效并不是啥子提高什么效率的,而是保证效率的。。

记得那是很久很久以前了。。在我还在研究数据库链接的时候。。睡眼朦胧,打开俺的.net项目,打开项目开始编程。
common.db db = new db();
DataTable dt = db.returnTable("select * from news where classId = 10 order by id desc");
this.Repeater1.DataSource = dt;
this.Repeater1.DataBind();

.........
.............

蒙蒙隆隆的我 睡着了。。醒来的时候已经是清晨了。。

看看项目还有2个小模块,顺手就写完了。。

打开首页,顺利编译,功能实现。。一宿的劳累没有白费,发布网站。。带着高兴的心情。。走出了办公室的大门。。

这时经理过来说客户打电话过来说网站极不稳定,打不了几个页面就报错了。我想不可能啊。。

几经排查,发现原来所有的模块,在 new db() 后,都没有 db.close() 。光首页调用这个就30多个模块,等于就开库30多次没关,刷3次首页,就相当与100次的开库不关,网站不报错才怪啊。。

于是在所有的模块里加上了db.close() ,可是能不能防患于未然呢。。毕竟我们都是人啊。。

隆重推出了我们的单件模式,当时如果使用了单件模式,等于最多的时候,也就是开了一条数据通道,等于就是开库1次而已,也不会造成那么大的性能损失了,当然,这可不是说你就不关库了。。嘿嘿。。

其实这个单件模式 简单的很。。他就是利用 private 将类的初始化私有,然后指定实例化方法GetInstance(动用静态变量),在GetInstance中看看如果第一次调用,就实例化,然后返回,如果已经有了这个对象了,就把对象返回。。

下面也没啥可说的了,给出 单件模式的 .Net 代码,这回自己懒得写了,直接从网上Copy下来了,总共就2行代码,不值当自己敲了。。嘎嘎。。这个是记录的日志的 单件类。。和我说的数据库连接 没有任何区别。。

困困的。。今天由于自己从新改版,就把网站数据全删了,传上去新的代码,发现数据库没有写权限了,于是就无所事事了。。也是这篇文章诞生的缘由吧。。 ( 俺小站zzcn.net ) 不要说俺广告哦。。

public class LogWriter

{

    //申明一个静态的变量,类型为类本身

    private static LogWriter _instance = null;

 

    //将类的构造函数私有化,使得这个类不可以被外界创建

    private LogWriter()

    {

    }

    //提供静态的方法,创建类的实例

    public static LogWriter GetInstance()

    {

        if (_instance == null)

        {

            _instance = new LogWriter();

        }

        return _instance;

    }

}

楼主
  5个月前   shengnet      :
如果数据库做单件的话。在并发时 会损失性能 很大。
回复  1楼 回到顶楼 
  5个月前   彭成刚      :
失性能 很大? 为什么呢。。比如我开库,不关,第2个开库,而实际上用单件的话,是把第一个开库的db对象传递到了第2个,应能应该没损失吧。。
回复  2楼 回到顶楼 
  5个月前   麒麟.NET      :
这种单件模式的实现方式无法保证线程安全
回复  3楼 回到顶楼 
  5个月前   暗香浮动      :
建议给出uml图。呵呵
回复  4楼 回到顶楼 
  5个月前   mjgforever      :
可以使用lock来进行线程安全。
回复  5楼 回到顶楼 
  5个月前   deerchao      :
数据库连接的话还是"多件模式"比较好一点,或者也叫"连接池".

限制只用一个连接的话比较浪费数据库的能力..
回复  6楼 回到顶楼 
  5个月前   金色海洋(jyk)      :
应该在这里
db.returnTable
打开连接,并且关闭连接。当然在中间要提取数据并填充到dataTable。

开关库要在 returnTable 这样的函数内部实现,外部不用关心。
回复  7楼 回到顶楼 
  5个月前   Justin      :
最好先重新排版
回复  8楼 回到顶楼 
  5个月前   Jeffrey Zhao      :
该using的地方还是要using……而且很优雅啊。
回复  9楼 回到顶楼 
  5个月前   Anders Cui      :
应该是Object Pool 模式
回复  10楼 回到顶楼 
  5个月前   彭成刚      :
已经重新排版了。。呵呵。。
回复  11楼 回到顶楼 
  5个月前   wenanry      :
使用这种双重锁的单键方式感觉比较好,线程安全的。
using System;

namespace SigletonPattern.Sigleton
{
/// <summary>
/// 功能:在C#用双重锁定实现单件模式
/// 编写:Terrylee
/// 日期:2005年12月06日
/// </summary>
public class DoubLockSigleton
{

private static volatile DoubLockSigleton instance;

/// <summary>
/// 辅助锁对象,本身没有意义
/// </summary>
private static object syncRoot = new Object();

/// <summary>
/// 构造方法改为Private
/// </summary>
private DoubLockSigleton()
{

}

public static DoubLockSigleton Instance
{
get
{
if (instance == null)
{
lock (syncRoot)
{
if (instance == null)
instance = new DoubLockSigleton();
}
}

return instance;
}
}

}
}
回复  12楼 回到顶楼 
  5个月前   韩现龙      :
你写的这个单件模式会有线程安全上的问题。原来我做的一个考试系统就是用的和你这个代码一样的方法,一开始也以为会能提高效率,岂不知,当有2、3个人的时候就会出现一些非常奇怪的问题,比如程序说什么Connection对象没有关闭啦,这个人登录之后显示的另外一个人的信息中啊之类的。当时我都蒙了,后来经网友们的提示才知道是这种用法有问题,后来又全改成了直接new对象的方法才没问题了。 由此我心生感慨,当不熟悉一门武艺时,千万不要在战场上使用它,否则,你可能用自己的刀把自己给伤了。
回复  13楼 回到顶楼 
  3个月前   彭成刚      :
好久没来了。。也好久没看设计模式了。。唉。。生活的现实。。不得不考虑。。暂时没有时间了。。
回复  14楼 回到顶楼 
  3个月前   Jonny      :
有线程的问题,建议去看看TerryLee的设计模式文章
回复  15楼 回到顶楼 
  1个月前   wanchangpeng      :
单键模式要考虑多线程问题,用数据库连接池性能比较好。
回复  16楼 回到顶楼 
  1个月前   水言木      :
这样不好,还是像Jeffrey Zhao说的在创建连接时用using,这样能保证及时关闭(如果你的连接字符串是完全一样的话(在Web.config中设置连接字符串就能保证一致了),其实只是把数据库连接放回连接池,并非真的关闭,连接池默认是启用的)
回复  17楼 回到顶楼 
  1个月前   李中华      :
在这里用单件模式,很不明智。
回复  18楼 回到顶楼 
  1个月前   李中华      :
楼上的兄弟们都说的不错。
回复  19楼 回到顶楼 
  3周前   笨→鸟(Bird)      :
17楼说得不错。
.net里的using可以自动帮你处理垃圾对象和回收资源。
回复  20楼 回到顶楼 
  3周前   TT.Net      :
单例模式用在并发这么大的数据方面明显是不明智的
开发中我把单例用在全局config和生成唯一的全局cache中。但都要保证线程安全,用双重判断是否null和LOCK
回复  21楼 回到顶楼 

你还不是小组成员,加入小组以后才能发布新主题!
> 返回“设计模式”


其他话题

1 26752