現在繼續考慮Order,在企業中訂單有很多種,運輸單、出庫單、外借單、報關單等等。是以應該把Order作為基類,然後其他訂單從該類派生。
現在我們再看一下使用者業務流程:當不同的使用者角色建立了不同的訂單,然後系統将這些訂單彙總到公司的審計部,當審計通過後,訂單将轉向各自需要處理的業務部門。
為了實作這個方案,我們在Order聲明了一個Send方法。

public class Order
{
public string OrderID;
public readonly DateTime CreateDate = DateTime.Now;
public virtual void Send()
{System.Console.WriteLine("Order");}
}
由于Send聲明為virtual的,是以為其子類的各訂單提供了多态的行為。
public class ConsignationBill : Order
{
public override void Send()
System.Console.WriteLine("ConsignationBill");
}
public class DispatchBill : Order
System.Console.WriteLine("DispatchBill");
public class WarehouseBill : Order
System.Console.WriteLine("WarehouseBill");
現在考慮一個很實際的處理問題,當審計部門通過了訂單的稽核,需要執行Send方法,以便将訂單轉到業務相應的部門。那我們希望有一個類來處理對稽核後的訂單的任務傳遞
public class Audit
private readonly Order tmpOrder;
public Audit(Order order)
tmpOrder = order;
public void AuditTask()
tmpOrder.Send();
}

測試一下

new Audit(new ConsignationBill()).AuditTask();

new Audit(new DispatchBill()).AuditTask();

new Audit(new WarehouseBill()).AuditTask();
通過了,效果不錯。
現在考慮更多情況,Send很明顯是用于業務流轉的方法,除了訂單,其他業務資料也會有流轉的要求,為了統一,很顯然,應該用到接口
public interface ISend
void Send();
更特别的是,不是所有的單據都有業務流轉的行為,所有不能讓Order去實作ISend接口,而是由Order的各子類去按實際情況分别實作ISend。
是以剛才的類的實作為

public class ConsignationBill : Order,ISend
public void Send()
public class DispatchBill : Order, ISend
public class WarehouseBill : Order, ISend
現在我們如果要求Audit能夠正常調用Send的方法,那Audit的實作為

private readonly ISend sender;
public Audit(ISend Sender)
sender = Sender;
public void AuditTask()
System.Console.WriteLine(sender.GetType().ToString());
sender.Send();
}
ok,雖然修改了Audit,但對調用者完全沒有影響。那還有新的要求嗎?有!
現在Audit類能接受所有實作了ISend的類,現在要求更嚴謹的處理:Audit類隻能處理Order的子類,且該子類必須實作了ISend的接口。
暈啊,怎麼寫啊?使用反射幫忙

if (sender.GetType().BaseType.Name == "Order")
System.Console.WriteLine(sender.GetType().BaseType.Name);
能不能代碼更簡潔簡單呢?可以,用泛型的限制能力
public class TAudit<T> where T : Order, ISend
private readonly T sender;
public TAudit(T Sender)
以上說明該泛型能接受的對象是從Order繼承,且實作了ISend接口,執行個體化的代碼為
new TAudit<ConsignationBill>(new ConsignationBill()).AuditTask();
new TAudit<DispatchBill>(new DispatchBill()).AuditTask();
new TAudit<WarehouseBill>(new WarehouseBill()).AuditTask();
使用泛型的限制,能讓代碼更加的清晰和簡單。
本文轉自shyleoking 51CTO部落格,原文連結:http://blog.51cto.com/shyleoking/806247