单例模式
保证一个类仅有一个实例,并提供一个访问它的全局访问点,也就是说应用该模式的一个类只有一个实例。即一个类只有一个对象实例。.
单例模式分类
饿单例模式:类加载时实例化一个对象给自己的引用。
懒单例模式:调用取得实例的方法如getInstance时才会实例化对象
单利模式结构图:
举例:为form1添加子窗体,要求点击菜单子窗体只出现一次
//form1代码
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
this.IsMdiContainer = true;
}
private FormToolbox ftb; //实例化form2
private void toolStripMenuItemToolboxToolStripMenuItem_Click(object sender, EventArgs e)
{
FormToolbox.GetInstance().Show() //GetInstance确保代码在多线程情况下的唯一性
}
}
//form2代码将判断加入到form2窗体,自己是否实例化自己判断
public partial class FormToolbox : Form
{
private static FormToolbox ftb = null;
public FormToolbox()
{
InitializeComponent();
}
public static FormToolbox GetInstance ()
{
if (ftb == null || ftb.IsDisposed) //判断是否为null 如果为null 则说明没有被实例化过
{
ftb = new FormToolbox();
ftb.MdiParent = Form1.ActiveForm;
}
return ftb;
}
}
多线程时的单例:
可以给进程加一把锁,确保一个线程位于代码的临界区,另外一个线程不进入进阶区,如果其他线程试图进入锁定的代码,则它将一直等待,直到该对象被释放。
public static FormToolbox GetInstance ()
{
lock(syncRoot) // lock确保一个线程位于代码的临界区,另外一个线程不进入进阶区,如果其他线程试图进入锁定的代码,则它将一直等待,直到该对象被释放。
{
if (ftb == null || ftb.IsDisposed) //判断是否为null 如果为null 则说明没有被实例化过
{
ftb = new FormToolbox();
ftb.MdiParent = Form1.ActiveForm;
}
}
return ftb;
}
作用:
控制资源使用,通过线程同步来控制资源的并发访问;
控制实例产生的数量,达到节约资源的目的;
优点:
1、减少内存开销,尤其是频繁的创建和销毁实例
2,避免对资源的过多利用
缺点:
1,不适用与变化的情况
2、违背了“单一职责原则”,一个类只重视内部关系,而忽略外部关系。