有一种设计模式叫回调

来源:互联网 发布:js 对象转字符串 编辑:程序博客网 时间:2024/05/21 22:21

一、回调是一种常见的程序设计模式。在这种模式中,可以指出某个特定事件发生时应该采取的动作。例如,可以指出在按下鼠标或选择某个菜单项时应该采取什么行动。
1.在C#中,我们会定义一个委托用来传递回调函数,请看下面代码,在A类里面调用B类的ShowAssociateRuleView的方法时传递了一个匿名委托(即回调函数),
在ShowAssociateRuleView方法中触发了传过来的onComplete,即回调了A传过来的匿名委托。
 Class A
 {
  /// <summary>
    /// 查看二级关联授权情况
    /// </summary>
    /// <param name="sender">sender</param>
    /// <param name="e">RoutedEventArgs</param>
    private void btnSeeSencondAssociate_Click(object sender, RoutedEventArgs e)       
      {
         B bclass=new B();
         //这里调用B类的ShowAssociateRuleView方法,并将匿名委托作为参数传过去
     bclass.ShowAssociateRuleView(delegate
                  {
                      DataCenterSwitchService.Instance.RevertContext();
                  });
      }
  }
  
   Class B
   {
   /// <summary>
      /// 弹出“一二级关联设置”自定义分组规则界面.
      /// </summary>
      /// <param name="onComplete">onComplete</param>
      public void ShowAssociateRuleView(Action onComplete)
      {           
          Dialogs.ShowModelDialog(
              this,
              "查看关联情况",
              delegate(object sender, WindowClosedEventArgs e)
              {
                //这里触发回调方法
                  if (onComplete != null)
                  {
                      onComplete();
                  }
              },
              null,
              new Size(950, 600));
      }
  }
 
  2.在java中如何实现回调呢?在java中可以利用接口来传递回调方法,其实有时候我们可以把C#中的委托比作只有一个方法的接口。
  举例:上级经理张三分配开发任务给李四,李四写完代码后要通知上级代码检查。显然,张三不一定要一直看着李四直到代码写完,在李四写代码的过程中可以干其他事情。
  代码如下:
  先约定一个接口
  public interface ICallBack {
 void execute();
 }
 
 上级张三类:
 public class Zhangsan { 
  private void CallLisi() throws InterruptedException {
   Lisi lisi=new Lisi();
   //上级张三下发任务给李四
   //这里传递了一个实现了ICallBack接口的匿名类给Lisi类的coding方法
   lisi.coding(new ICallBack() {    
    @Override
    public void execute() {
     System.out.println("张三正在检查李四的代码。。");
    }
   });
  } 
 }
 
 下级李四类:
 public class Lisi {
 //接收任务
 public void coding(ICallBack onComplete) throws InterruptedException {  
  System.out.println("李四正在写代码。。。");
  Thread.sleep(5000);
  System.out.println("李四写完代码了。。。");
  //这里回调,通知老大张三
  onComplete.execute();
 }
}


二、延伸
1.上例中如果存在王五类(配置部人员),代码如下:
public class Wangwu {
 //李四写完代码后配置部王五要合并代码
 private void CallLisi() throws InterruptedException {
  Lisi lisi=new Lisi();
  lisi.coding(new ICallBack() {    
   @Override
   public void execute() {
    System.out.println("配置部王五在合并李四写的代码。。");
   }
  });
 }
}

这里Zhangsan类和Wangwu类在李四写完代码后干的活儿都不同,那么我们就可以写两个实现了ICallBack接口的类传给Lisi.coding方法,是不是符合了分离变化点的原则。
在用Java写JDBC代码的时候,通常我们会把作映射的一部分抽取出来,由调用方去实现,这就分离了变化点。如下代码,通常我们的变化部分就在做实体映射部分,我们就需要提取一个接口
由调用方来实现。

public List<User> query() { 
 
    List<User> userList = new ArrayList<User>(); 
    String sql = "select * from User"; 
 
    Connection con = null; 
    PreparedStatement pst = null; 
    ResultSet rs = null; 
    try { 
        con = HsqldbUtil.getConnection(); 
        pst = con.prepareStatement(sql); 
        rs = pst.executeQuery(); 
 
        User user = null; 
        while (rs.next()) { 
 
            user = new User(); 
            user.setId(rs.getInt("id")); 
            user.setUserName(rs.getString("user_name")); 
            user.setBirth(rs.getDate("birth")); 
            user.setCreateDate(rs.getDate("create_date")); 
            userList.add(user); 
        } 
 
 
    } catch (SQLException e) { 
        e.printStackTrace(); 
    }finally{ 
        //关闭数据库连接部分。。。。。
    } 
    return userList; 

2.在上面的例子中用到了匿名类,格式如new ICallBack(){} 或new 抽象类如new MouseAdapter(){},通常在不需要重用并且代码行数很少情况下,可以使用匿名类方式。


个人拙见,请勿拍砖,指正点评即可,o(∩_∩)o...