享受代码,享受人生

SOA is an integration solution. SOA is message oriented first.
The Key character of SOA is loosely coupled. SOA is enriched
by creating composite apps.
  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

Delegate和Command Pattern

Posted on 2005-02-03 16:50  idior  阅读(8510)  评论(24编辑  收藏  举报

前天写了一篇有关Delegate的随笔,随后又看了看吕震宇的一篇相关随笔.发现Delegate有些问题.
Delegate就是接口,我是这样理解它的.
后来发现Delegate比起接口可以"乱用".因为它只要方法的签名一样就可以替换.比如下面这个例子.

public class Client 

     
public  dalegate int AddHandle(int a, int b); 
     
public  AddHandle Add ; 
        
     
public  void Do()
     
{
       
//
       Add(2,3);
     }

}
 
public class Math 

    
public int Add(int a,int b) 
    

          
return a+b; 
    }
 
     
    
public int Sub(int a,int b) 
    

          
return a-b; 
    }
     
}
 

 这下可好,如果象下面这样用,结果岂不变成-1了

Client c=new Client(); 
c.Add 
= new Client.AddHandle(new Math().Sub); 
c.Do();

 如果用接口,约束性就强了点.

public class Client
{
    
public AddHandle iadder;
        
public void Do()
        
{
           
//
           iadder.Add();
        }

}


public interface AddHandle
{
    
int Add(int a, int b);
}


public class Client
{
    
public AddHandle Add;
}


public class Math : AddHandle
{
    
public int Add(int a, int b)
    
{
        
return a + b;
    }


    
public int Sub(int a, int b)
    
{
        
return a - b;
    }

}


Client c
=new Client(); 
c.iadder
=new Math();
c.Do();

这样不太可能出上面那样的错误.
不过Delegate这么灵活也不全是错.
如果Math中的方法是Static的(也是很有可能的),那接口就傻眼了,但是Delegate照样能搞定.
根据Delegate的这个灵活的特点,我想了一个合理的应用---计算工资.

public  delegate double OperationHandle(double a, double b);

public class Math
{
    
public int Add(int a,int b)
    
{
          
return a+b;
    }

    
    
public int Sub(int a,int b)
    
{
          
return a-b;
    }

}


private int wage= 0;
public void ModifyWage(int  value,OperationHandle operation)
{
 
int newWage= operation(wage, value);
 wage
= newWage;
}

加加减减,甚至乘除,只要绑定上不同的operation就ok了,这样岂不是很方便?
如果用接口实现呢?

public interface OperationHandle
{
 
int Execute(int a, int b);
}


public class Add : OperationHandle
{
 
public int Execute(int a, int b)
 
{
  
return a + b;
 }

}

public class Sub: OperationHandle
{
 
public int Execute(int a, int b)
 
{
  
return a - b;
 }

}


private int  wage= 0;
public void ModifyWage(int value,OperationHandle operation)
{
 
int  newWage= operation.Execute(wage, value);
 wage
= newWage;
}

 可以看出这就是Command模式.
还有好玩的,Delegate不是可以使用多播嘛(+=),用在这里就更好玩了.

public  delegate int OperationHandle(int a, int b);

public class Math
{
    
public int Add(int a,int b)
    
{
          
return a+b;
    }

    
    
public int Sub(int a,int b)
    
{
          
return a-b;
    }

}


private int wage= 0;
public void ModifyWage(int [] value,OperationHandle operation)
{
                
int i=0;
                
foreach(OperationHandle oh in operation.GetInvokeList())
                
{
        
int newWage= oh(wage, value[i]);
        wage
+= newWage;
                                   i
++;
                }

}

 很方便吧,接口也能做.Command加上Composition,不过要想变换参数似乎有点困难,(这仅仅是个例子,不考虑那么多了)


public class Composite : OperationHandle
{
    IList operations 
= new ArrayList();

    
public int Execute(int a, int b)
    
{
        
int result = 0;
        
foreach(Operation o in operations)
            result 
+= o.Execute(a, b);

        
return result;
    }


    
public void AddOperation(Operation o)
    
{
        operations.Add(o);
    }

}
看完这些你感觉怎么样?难怪有人说.net的架构师是Delegate先生,delegate做的事,interface
基本上都能做,不过delegate是带来了不少方便,不过初学者比较难理解delegate这个概念,而且如前文所说
delegate在带来灵活性的同时也带来了一定的危险.