這是軟體工程中的概念
首先要知道一個軟體是由多個子程式組裝而成,
而一個程式由多個模組(方法)構成!
而內聚就是指程式內的各個模組之間的關係緊密程度,
偶合就是各個外部程式(子程式)之間的關係緊密程度.
所以很易明白,為什麼要高內聚?模組之間的關係越緊密,出錯就越少!低偶合?子程式間的關係越複雜,就會產生更多的意想不到的錯誤!會給以後的維護工作帶來很多麻煩!
c#語言的一大特點就是
高彙總,低耦合。而委託也很明顯的體現了這樣的一個特徵。委託的價值並不在於它能幫你解決什麼難題,而在於它能協助你最佳化你的程式。
很多情況下不用委託我們也能完成工作,也許偶爾會覺得使用委託更加麻煩,但是正如前面所說委託能使代碼更加的低耦合,更加具有可讀性,更加容易根據需求的
改變而改變,也更加的簡少了代碼量。
既然有那麼多優點我們當然要使用,如果你對委託的優點仍然有所懷疑,那麼我們一起完成下面的例子。
有一個運動員,他叫green,他每周要訓練三天,周一,周二和周三。而他每天訓練完成後都要做不同的事情,但是這些事情是有規律的,他周一要將訓練的分
數交給manager,周二不用交了,但是他要自己記錄下這個分數,周三他不用交也不用記錄,但是他要把他的分數給他的隊友看。
這樣一個遊戲規則,我們試著用代碼來實現它,首先,我們不考慮委託。
顯然,這個過程需要運動員在每次完成訓練後傳遞一些資訊(參數)給某些方法(提交給manager的方法,記錄的方法,傳遞給其他隊友的方法)我們把這三
個方法寫在一個DoSomeThing類中,result是我們定義的一個string用來記錄結果。
public class DoSomeThing
{
public void GiveCodeToManager(object sender, CustomeEvetnArgs e)
{
result +=sender.ToString()+ "已經將分數:" + e.Code.ToString() + "送給Manager";
}
public void RecodeCode(object sender, CustomeEvetnArgs e)
{
result += sender.ToString() + "已經將分數:" + e.Code.ToString() + "記錄";
}
public void GiveCodeToOthers(object sender, CustomeEvetnArgs e)
{
result += sender.ToString() + "已經將分數:" + e.Code.ToString() + "給其他人";
}
}
//傳遞的參數中有一個CustomeEvetnArgs,
//這是我們自訂的傳遞資訊類。這個類將包含傳遞的分數,如下
public class CustomeEvetnArgs : EventArgs
{
private string _code;
public string Code
{
get { return _code; }
set { _code = value; }
}
}
//我們還要有一個player類,運動員類,
//這個類中要根據時間的不同來調用dosomething類中的方法,並傳遞參數
public class player
{
private string _code;
public string Code
{
get { return _code; }
set { _code = value; }
}
private string _thedate;
public string TheDate
{
get { return _thedate; }
set { _thedate = value; }
}
public void OnComplete()
{
CustomeEvetnArgs e = new CustomeEvetnArgs();
e.Code = this.Code;
DoSomeThing things = new DoSomeThing();
if (_thedate == "Mon")
{
things.GiveCodeToManager(this, e);
}
if (_thedate == "Tues")
{
things.RecodeCode(this, e);
}
if (_thedate == "Wed")
{
things.GiveCodeToOthers(this, e);
}
}
}
//這樣基本類型就完成了,我們現在來調用它們
player green = new player();
green.Code = "A+";
green.TheDate = "Tues";
green.OnComplete();
Response.Write(result);
嗨,我們實現了這個遊戲。測試一下,確實沒有問題,如果你是一個細心的人也許你會回過頭來檢查你的代碼,是否會發現一些不盡人意的地方?你會發現運動員類
中包含的東西太多了,比如日期並不是一個運動員的屬性,運動員和日期有什麼關係呢?而運動員的唯一事件就是完成訓練,他不需要去管其他事情了,他訓練完了
太累了,還要去送分數和記錄成績?也許他應該有個助手去做這些事情,所以在運動員類中並不應該出現那些if,他們使代碼的耦合度太高了,當一個運動員想要
改變他的訓練流程時,他不得不改變player類。於是,委託出場了。
定義一個委託,使用delegate關鍵字,後面跟上他的參數,這個委託是要委託他去處理dosomething中的方法的,所以委託和這些方法的簽名要
一致。 public delegate void MyDelegate(object sender,
CustomeEvetnArgs e);
於是有了這個助手,green輕鬆多了,他終於不用管今天是星期幾了,我們重新改一下player類,這個類中去掉了thedate屬性,也沒有了if,
只有一個委託oncomplete事件在運動員OnComplete時觸發。
public class player
{
private string _code;
public string Code
{
get { return _code; }
set { _code = value; }
}
public event MyDelegate oncomplete;
public void OnComplete()
{
CustomeEvetnArgs e = new CustomeEvetnArgs();
e.Code = this.Code;
if (oncomplete != null)
{
oncomplete(this, e);
}
}
}
//而這個助手要看今天是星期幾,然後執行相應的方法,date是今天的日期。
DoSomeThing things = new DoSomeThing();
if (date == "Mon")
{
green.oncomplete += new MyDelegate(things.GiveCodeToManager);
}
if (date == "Tues")
{
green.oncomplete += new MyDelegate(things.RecodeCode);
}
if (date == "Wed")
{
green.oncomplete += new MyDelegate(things.GiveCodeToOthers);
}
green.OnComplete();
Response.Write(result);
這樣萬一遊戲流程有了改變,那也跟green無關了,他只要專心訓練,其他的由這個助手進行改動。
委託可以通過+= ,-=來增加和消除他在星期幾所委託的方法。
高彙總 低耦合,是委託的一個很重要的用途。
大家也可以點擊我的部落格(點我的頭像)查看,有興趣的可以一起討論。