高聚合低耦合

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无关了,他只要专心训练,其他的由这个助手进行改动。 委托可以通过+= ,-=来增加和消除他在星期几所委托的方法。 高聚合 低耦合,是委托的一个很重要的用途。 大家也可以点击我的博客(点我的头像)查看,有兴趣的可以一起讨论

//-------------------------------------------------Code-----------------------------------------------------------------

using System; using System.Data; using System.Configuration; using System.Collections; using System.Web; using System.Web.Security; using System.Web.UI; using System.Web.UI.WebControls; using System.Web.UI.WebControls.WebParts; using System.Web.UI.HtmlControls; using System.Data.sqlClient;

public partial class DEMO : System.Web.UI.Page { protected void Page_Load(object sender,EventArgs e) { //Play play = new Play(); //play.Code = "A+"; //play.Thedate = "Mon"; //Response.Write(play.OnComplete()); New_Play green = new New_Play(); string date = "Mon"; green.Code = "A+"; 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(things.Result); } }

public class DoSomeThing { private string result; public string Result { get { return result; } set { result = value; } }

public void GiveCodetoManager(object sender,CustomeEventnArgs e) { result +=sender.ToString()+ "已经将分数:" + e.Code.ToString() + "送给Manager"; } public void RecodeCode(object sender,CustomeEventnArgs e) { result += sender.ToString() + "已经将分数:" + e.Code.ToString() + "记录"; } public void GiveCodetoOthers(object sender,CustomeEventnArgs e) { result += sender.ToString() + "已经将分数:" + e.Code.ToString() + "给其他人"; } }

public class CustomeEventnArgs:EventArgs { private string _code; public string Code { get{ return _code; } set{ _code = value; } } }

public class Play { private string _code; private string _thedate; public string Code { get{ return _code; } set{ _code = value; } }

public string Thedate { get { return _thedate; } set { _thedate = value; } }

public string OnComplete() { CustomeEventnArgs e = new CustomeEventnArgs(); 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); } return things.Result; } }

public delegate void MyDelegate(object sender,CustomeEventnArgs e); public class New_Play { private string _code; public string Code { get { return _code; } set { _code = value; } }

public event MyDelegate oncomplete; public void OnComplete() { CustomeEventnArgs e = new CustomeEventnArgs(); e.Code = this.Code; if (oncomplete != null) { oncomplete(this,e); } } }

相关文章

迭代器模式(Iterator)迭代器模式(Iterator)[Cursor]意图...
高性能IO模型浅析服务器端编程经常需要构造高性能的IO模型,...
策略模式(Strategy)策略模式(Strategy)[Policy]意图:定...
访问者模式(Visitor)访问者模式(Visitor)意图:表示一个...
命令模式(Command)命令模式(Command)[Action/Transactio...
生成器模式(Builder)生成器模式(Builder)意图:将一个对...