- 單例模式的引入
- 在講解什么是單例模式之前,我們先引入這樣一個問題,在Winform開發的過程中,實現點擊一個按鈕彈出一個窗體,那么怎樣控制點擊按鈕后彈出額窗體只有一個,如果窗體已經彈出,就不再彈出新的窗體。解決方案有如下三種(先做簡單的介紹,之后逐一進行詳細講解)
- 方案一:使用ShowDialog()方法彈出,這種方法也是最簡單粗暴屌到家的方法
- 方案二:使用邏輯語句判斷當前窗體是否已經打開,如果打開,就不知執行再次打開操作
- 方案三:使用單例模式(引入單例模式)
- 在講解什么是單例模式之前,我們先引入這樣一個問題,在Winform開發的過程中,實現點擊一個按鈕彈出一個窗體,那么怎樣控制點擊按鈕后彈出額窗體只有一個,如果窗體已經彈出,就不再彈出新的窗體。解決方案有如下三種(先做簡單的介紹,之后逐一進行詳細講解)
- 示例工程建立講解
- 建立一個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(); }
- 完成