- 單例模式的引入
- 在講解什么是單例模式之前,我們先引入這樣一個問題,在Winform開發的過程中,實現點擊一個按鈕彈出一個窗體,那么怎樣控制點擊按鈕后彈出額窗體只有一個,如果窗體已經彈出,就不再彈出新的窗體。解決方案有如下三種(先做簡單的介紹,之后逐一進行詳細講解)
- 方案一:使用ShowDialog()方法彈出,這種方法也是最簡單粗暴屌到家的方法
- 方案二:使用邏輯語句判斷當前窗體是否已經打開,如果打開,就不知執行再次打開操作
- 方案三:使用單例模式(引入單例模式)
- 示例工程建立講解
- 建立一個Winform工程
- Form1為主窗體,添加Form2窗體為被彈出窗體,在窗體上放置兩個按鈕,button1和button2,這兩個按鈕被點擊的時候都彈出Form2
- 詳解方案一:
- 這種方法簡單實現不能,只要在這兩個按鈕的click事件中添加如下代碼就可以實現,但點擊后,如果Form2窗體不關閉的話,Form1主窗體無法繼續操作,詳情請查閱ShowDialog()方法的使用
private void button1_Click(object sender, EventArgs e)
{
Form2 f2 = new Form2();
f2.ShowDialog();
}
private void button2_Click(object sender, EventArgs e)
{
Form2 f2 = new Form2();
f2.ShowDialog();
}
Form2 f2 = null;
private void button1_Click(object sender, EventArgs e)
{
if (f2 == null||f2.IsDisposed)
{
f2 = new Form2();
f2.Show();
}
else
{
f2.Show();
}
}
private void button2_Click(object sender, EventArgs e)
{
if (f2 == null || f2.IsDisposed)
{
f2 = new Form2();
f2.Show();
}
else
{
f2.Show();
}
}
-
- 代碼簡單不解釋,這里重點說一下IsDisposed屬性的使用,如果判斷該屬性的話,當點擊一次按鈕,關閉Form2窗體,再次點擊的時候會報錯,請自己嘗試,因為當關閉窗體的時候,f2變量並沒有重置為null,但是窗體已經被釋放了,所以需要判斷一下;IsDisposed:獲取一個值,該值指示控件是否已經被釋放;如果控件已經被釋放,則為 true;否則為 false。
- 詳解方案三:
- 這種方法也是這次的重點就是使用了單例模式進行編碼,所謂優缺點自行找資料分析,學習只是就是想要使用不同的手段實現相同的功能,這樣才能解放自己的思維和思考方式
- 在講解這種之前,我們先講解一下什么是單例模式?怎么事項單例模式?單例模式通俗的來講就是控制一個類只能new一個對象
- 直接上代碼,單例模式類的示例代碼
/// <summary>
/// 這個類只能new一個對象
/// </summary>
public class Singleton
{
private static Singleton _instance;
private static readonly object syn = new object();
/// <summary>
/// 把類的構造函數訪問權限設置為private,則該類不能在外界被new了
/// </summary>
private Singleton() { }
/// <summary>
/// 在當前類型中創建一個靜態的方法,用該靜態方法來返回一個對象
/// </summary>
/// <returns></returns>
public static Singleton CreateInstance()
{
if (_instance == null)
{
lock (syn)
{
if (_instance == null)
{
_instance = new Singleton();
}
}
}
return _instance;
}
}
-
- 以上代碼,使用線程鎖解決了多線程訪問的時候發生的問題
- 使用如下代碼進行調用判斷
static void Main(string[] args)
{
Singleton s1 = Singleton.CreateInstance();
Singleton s2 = Singleton.CreateInstance();
//確定指定的 System.Object 實例是否是相同的實例。
Console.WriteLine(object.ReferenceEquals(s1, s2));
Console.ReadKey();
}
-
- 返回的結果為Ture
- 那么以上就是單例模式的簡單示例,接下來我們來解決一下之前窗體彈出的問題
- Form2窗體代碼
public partial class Form2 : Form
{
private Form2()
{
InitializeComponent();
}
private static Form2 _f2;
public static Form2 CreateForm()
{
if (_f2 == null || _f2.IsDisposed)
{
_f2 = new Form2();
}
return _f2;
}
}
private void button1_Click(object sender, EventArgs e)
{
Form2 f2 = Form2.CreateForm();
f2.Show();
}
private void button2_Click(object sender, EventArgs e)
{
Form2 f2 = Form2.CreateForm();
f2.Show();
}