用委托来减少代码的耦合

       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无关了,他只要专心训练,其他的由这个助手进行改动。

委托可以通过+= ,-=来增加和消除他在星期几所委托的方法。

高聚合 低耦合,是委托的一个很重要的用途。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值