回調模式小結(一)

目的:

在形如

  1. func(){
  2.     head head head...
  3.     act();
  4.     tail tail tail...
  5. }

的代碼中,常常會出現 act 并不是特定的某個動作,可能需要外界定制,如

  1. void main(){
  2.     int a = 2, b = 3;
  3.     
  4.     double r=a + b;
  5.     printf("%lf/n", r);
  6. }

 

第 4 行的運算式可能是  a-b, a * b, 或者 sqrt(a*a + b*b),此時便需要將運算式傳進 main 函數。

 

假如運算式有幾種可以確定,可以使用:

  1. void main(char op){
  2.     int a = 2, b = 3;
  3.     
  4.     double r= 0;
  5.     switch(op){
  6.       case '+': r = a + b; break;
  7.       case '-' : r = a - b ; break;
  8.       case '*' : r = a * b ; break;
  9.       case '?' : r = sqrt(a * a + b * b); break;
  10.     }
  11.     printf("%lf/n", r);
  12. }

 

代碼看起來比較臃腫。不幸的是,事先并不知道确定有哪些表達式,所以雖然這么賣力,也沒能解決問題。

 

我們期望的方案應該是這樣的:

  1. void main(expr){
  2.     int a = 2, b = 3;
  3.     double r = expr(a, b);
  4.     printf("%lf/n", r);
  5. }

這個。。好像泄露謎底了。 這種由另外的開發階段來提供表達式的方式叫回調。

 

在 c 語言里,能做到這樣的方法是函數指針:

  1. void fun(double(*expr)(intint)){
  2.     int a = 2, b = 3;
  3.     double r = expr(a, b);
  4.     printf("%lf/n", r);
  5. }
  6. double add(int a, int b){return a + b;}
  7. double subtract(int a, int b){return a - b;}
  8. double multi(int a, int b){return a * b;}
  9. double xian(int a, int b){return sqrt(a * a + b * b);}
  10. void main(){
  11.     fun(&add);
  12.     func(&subtract);
  13.     func(&multi);
  14.     func(&xian);
  15. }

此方法順利的實現了回調的目的。所以在以後還可以方便的塞新算法進去。

 

在 java 里沒有函數指針,所以我們不能指望函數指針這種方式,萬一指錯了怎么辦,函數指針好用,也很危險。在 java 里的做法有這么幾種。

 

第一、聲明一個表達式類或接口,每一種運算都這個類派生,如下:

  1. public class Test {
  2.     interface Expr {
  3.         double eval(int a, int b);
  4.     }
  5.     private static void fun(Expr expr) {
  6.         int a = 2, b = 3;
  7.         double r = expr.eval(a, b);
  8.         System.out.println(r);
  9.     }
  10.     public static void main(String[] args) {
  11.         fun(new Expr() {
  12.             @Override
  13.             public double eval(int arg0, int arg1) {
  14.                 return arg0 + arg1;
  15.             }
  16.         });
  17.         fun(new Expr() {
  18.             @Override
  19.             public double eval(int arg0, int arg1) {
  20.                 return arg0 - arg1;
  21.             }
  22.         });
  23.         fun(new Expr() {
  24.             @Override
  25.             public double eval(int arg0, int arg1) {
  26.                 return arg0 * arg1;
  27.             }
  28.         });
  29.         fun(new Expr() {
  30.             @Override
  31.             public double eval(int arg0, int arg1) {
  32.                 return Math.sqrt(arg0 * arg0 + arg1 * arg1);
  33.             }
  34.         });
  35.     }
  36. }

這段代碼看上去比較長。幸運的是在 eclipse 的幫助下,也沒打幾個字。

 

第二種方法、使用 override 特性:

  1. public abstract class Test {
  2.     public void fun() {
  3.         int a = 2, b = 3;
  4.         double r = expr(a, b);
  5.         System.out.println(r);
  6.     }
  7.     abstract double expr(int a, int b);
  8.     public static void main(String[] args) {
  9.         new Test() {
  10.             @Override
  11.             double expr(int arg0, int arg1) {
  12.                 return arg0 + arg1;
  13.             }
  14.         }.fun();
  15.         new Test() {
  16.             @Override
  17.             double expr(int arg0, int arg1) {
  18.                 return arg0 - arg1;
  19.             }
  20.         }.fun();
  21.         new Test() {
  22.             @Override
  23.             double expr(int arg0, int arg1) {
  24.                 return arg0 * arg1;
  25.             }
  26.         }.fun();
  27.         new Test() {
  28.             @Override
  29.             double expr(int arg0, int arg1) {
  30.                 return Math.sqrt(arg0 * arg0 + arg1 * arg1);
  31.             }
  32.         }.fun();
  33.     }
  34. }

最後是來自函數式編程家族的 javascript:

  1. function fun(expr){
  2.     var a=2, b = 3;
  3.     var r = expr(a, b);
  4.     alert(r);
  5. }
  6. fun(function(){return a + b;});
  7. fun(function(){return a - b;});
  8. fun(function(){return a * b;});
  9. fun(function(){return Math.sqrt(a  * a + b * b);});

代碼很短很瀟灑。

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值