工廠方法與簡單工廠
- 簡單工廠,最大優點是工廠類中包含了必要的邏輯判斷,對於客戶端來說,去除了與具體產品的依賴;但是,一旦要新增產品,就必須修改工廠類的判斷邏輯,這明顯違背的開放-封閉原則(對擴展開放,對修改封閉)
- 工廠方法,則定義了一個創建對象的接口,讓子類決定實例化哪一個類。新增產品時,只需要新增子類即可;但是,需要修改客戶端。
- 工廠方法+反射,可以很好的解決工廠方法在需求變動時,需要改動客戶端代碼的缺陷。
深拷貝與淺拷貝
- 淺拷貝,只拷貝引用
- 深拷貝,會重新實例化引用中的內容
模板方法
- 過程一致,但是實現有差異,可以使用模板方法
- 把不變的行爲搬到超類,把差異放到子類,來去除子類中的重複代碼
單實例
- 線程安全
- 惰性實例化
- 避免反覆枷鎖
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();
}
}