設計模式

工廠方法與簡單工廠

  1. 簡單工廠,最大優點是工廠類中包含了必要的邏輯判斷,對於客戶端來說,去除了與具體產品的依賴;但是,一旦要新增產品,就必須修改工廠類的判斷邏輯,這明顯違背的開放-封閉原則(對擴展開放,對修改封閉)
  2. 工廠方法,則定義了一個創建對象的接口,讓子類決定實例化哪一個類。新增產品時,只需要新增子類即可;但是,需要修改客戶端。
  3. 工廠方法+反射,可以很好的解決工廠方法在需求變動時,需要改動客戶端代碼的缺陷。

深拷貝與淺拷貝

  1. 淺拷貝,只拷貝引用
  2. 深拷貝,會重新實例化引用中的內容

模板方法

  1. 過程一致,但是實現有差異,可以使用模板方法
  2. 把不變的行爲搬到超類,把差異放到子類,來去除子類中的重複代碼

單實例

  • 線程安全
  • 惰性實例化
  • 避免反覆枷鎖
 public sealed class Singleton
 {
     static Singleton instance = null;
     private static readonly object padlock = new object();

     private Singleton()
     {
     }

     public static Singleton Instance
     {
         get
         {
             if (instance == null)
             {
                 lock (padlock)
                 {
                     if (instance == null)
                     {
                         instance = new Singleton();
                     }
                 }
             }
             return instance;
         }
     }
 }

觀察者

採用.NET事件機制和通用方法實現的觀察者模式
NewMailEventArgs.cs(Subject/Observer之間的傳遞參數)

    public class NewMailEventArgs : EventArgs
    {
        public NewMailEventArgs(string from, string to, string subject)
        {
            From = from;
            To = to;
            Subject = subject;
        }

        public string From { get; set; }
        public string To { get; set; }
        public string Subject { get; set; }
    }

MailManager_Event.cs (基於.NET事件機制實現的Subject/Observer)

	//Subject
    public class MailManager_Event
    {
        public event EventHandler<NewMailEventArgs> NewMail;
        
        public void OnNewMail(NewMailEventArgs e)
        {
            EventHandler<NewMailEventArgs> temp = NewMail;
            if (temp != null)
            {
                temp(this, e);
            }
        }

        public void SimulateNewMail(String from, String to, String sub)
        {
            NewMailEventArgs e = new NewMailEventArgs(from, to, sub);

            OnNewMail(e);
        }

        public void add(EventHandler<NewMailEventArgs> handler)
        {
            //實現往集合中添加元素,C#因爲事件機制已經將其做好
            this.NewMail += handler;
        }

        public void remove(EventHandler<NewMailEventArgs> handler)
        {
            this.NewMail -= handler;
        }
    }
	
	// Observer1
    class Computer
    {
        public void RunCompute(object sender, NewMailEventArgs e)
        {
            Console.WriteLine("Computer received messages: from {0} to {1} subject {2}", e.From, e.To, e.Subject);
        }
    }

	// Observer2
    class Watch
    {
        public void RunWatch(object sender, NewMailEventArgs e)
        {
            Console.WriteLine("Watch received messages: from {0} to {1} subject {2}", e.From, e.To, e.Subject);
        }
    }

MailManager_General.cs(基於通用方法實現的Subject/Observer)

	public class MailManager_General
    {
        public List<IObservor> observerList;

        public MailManager_General()
        {
            observerList = new List<IObservor>();
        }

        public void OnNewMail(NewMailEventArgs e)
        {
            foreach (var item in observerList)
            {
                item.NotifyHandler(this, e);
            }
        }

        public void SimulateNewMail(String from, String to, String sub)
        {
            NewMailEventArgs e = new NewMailEventArgs(from, to, sub);

            OnNewMail(e);
        }

        public void add(IObservor observer)
        {
            //...非C#代碼,沒有事件機制,應該這樣處理:
            observerList.Add(observer);
        }

        public void remove(IObservor observer)
        {
            //...非C#代碼,沒有事件機制,應該這樣處理:
            observerList.Remove(observer);
        }
    }


    public interface IObservor
    {
        void NotifyHandler(object sender, NewMailEventArgs e);
    }

    public class Cellphone : IObservor
    {

        public void NotifyHandler(object sender, NewMailEventArgs e)
        {
            Console.WriteLine("Phone received messages: from {0} to {1} subject {2}", e.From, e.To, e.Subject);
        }

    }

    public class Fax : IObservor
    {
        public void NotifyHandler(object sender, NewMailEventArgs e)
        {
            Console.WriteLine("Fax received messages: from {0} to {1} subject {2}", e.From, e.To, e.Subject);
        }
    }

Program.cs (客戶端程序)

	class Program
    {
        static void Main(string[] args)
        {
            //======================================
            //C#事件機制: 
            //1. 觀察者無需都繼承自同一個基類,
            //2. 因此觀察者處理通知的執行函數名稱就可以自定義
            //主體(消息發佈者)
            var mgr = new MailManager_Event();

            //觀察者(消息訂閱者)
            Computer computer = new Computer();
            Watch watch = new Watch();

            //客戶端自行決定添加或移除
            mgr.NewMail += computer.RunCompute;
            mgr.NewMail += watch.RunWatch;

            //發佈消息
            mgr.SimulateNewMail("wangyahua", "liqiuhua", "play");

            //======================================
            //非C#,無事件機制的處理:
            //1. 觀察者必須繼承自同一個基類
            //2. 因此導致通知執行函數名稱只能在抽象觀察者接口中定義好,而無法由使用者自定義
            var mgr_g = new MailManager_General();
            Cellphone phone = new Cellphone();
            Fax fax = new Fax();
            mgr_g.add(phone);
            mgr_g.add(fax);

            //發佈消息
            mgr_g.SimulateNewMail("wangyahua", "liqiuhua", "eat");

            Console.ReadKey();
        }
    }
發佈了8 篇原創文章 · 獲贊 0 · 訪問量 361
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章