JDON中china of Responsibility模式的疑惑?

08-09-16 ITfuture
大家好:

这两天看了关于设计模式中职责链模式chain of Responsibility。我觉得它就是通过引用来决定下一个处理单位的.

使用这个模式接偶发送者和调用者之间的关系,也就是说发送者无需知道当前链上的那个对象进行处理。这样系统可以在不影响客户调用的情况下动态组织链和分配责任。

看了3种方式的演示后,比如例子中:

public class ConcreteHandler implements Handler{

  private Handler successor;

  public ConcreteHandler(Handler successor){

    this.successor=successor;

  }

  public void handleRequest(Request request){

    if (request instanceof HelpRequest){

      //这里是处理Help的具体代码

    }else if (request instanceof PrintRequst){

      request.execute();

    }else

      //传递到下一个

      successor.handle(request);

    }

  }

}

其中方法handleRequest里的实现我始终是不解?

顺便问问BANQ 在这个COR中,如果我增加一种处理format是不是应该增加一个formatHandler和一个formatRequest?

当我处于客户端调用的时候

问题是当我生成ConcreteHandler 类实例时候必然要给 他传 下一个的处理对象?那不是跟我上面说的概念相互矛盾么?

莫非我太局限于当前实例的代码?但是我怎么也明白不过来COR带来的

【发送者无需知道当前链上的那个对象进行处理。这样系统可以在不影响客户调用的情况下动态组织链和分配责任】

可能我的表达让大家会有误解,希望高人来解道啊!天天在线等...谢谢大家了

         

1
freebox
2008-09-16 17:27
发表一下我的理解:

链是什么样的呢?是一环一环的,这一环的前后是什么东西只有这一环自己知道

于是构造个接口:

interface Manager{
  void manageIt(int price);
  Manager setNextManager(Manager manager);
}
abstract class AbstractManager implements Manager{
  protected Manager next;
  Manager setNextManager(Manager manager){
    this.next=manager;
  }
}
<p>

再构造几个环子:

class ManagerOne extends AbstractManager{
  void manageIt(int price){
    if(price<=100){
      debug("here is One.I can manage it,do not post next,stop here");
    }else{
      next.manageIt(price);
    }
  }
}
class ManagerTwo extends AbstractManager{
  void manageIt(int price){
    if(price<=1000){
      debug("here is Two.");
    }else{
      next.manageIt(price);
    }
  }
}
class ManagerThree extends AbstractManager{
  void manageIt(int price){
    if(price<=10000){
      debug("here is Three.");
    }else{
      next.manageIt(price);
    }
  }
}
class ManagerLast extends AbstractManager{
  void manageIt(int price){
    if(price>10000){
      debug("here is Last.");
    }else{
      debug("What happened?why here?");
      throw new RuntimeException();
    }
  }
}
<p>

在客户端把环子串起来并实施调用

class Client{
  //invoke it before
  void init(){
    Manager one=new ManagerOne();
    Manager two=new ManagerTwo();
    Manager three=new ManagerThree();
    Manager last=new ManagerLast();
    one.setNextManager(two);
    two.setNextManager(three);
    three.setNextManager(last);
  }
  void test(){
    //数字200发言:其实我不知道到底哪个环在处理我,只要从第一个开始就可以了
    //它处理不了我也不知道,反正有一个环处理了,或者到最后扔回来一个异常。
    one.manageIt(200);
  }
}
<p>

[该贴被freebox于2008-09-16 17:35修改过]

ITfuture
2008-09-16 17:55
初始链的关系和分配责任是在客户端来完成的么?如果是的话哪么链还是暴露给了客户端。实际上客户端还是在维护这个链的关系。

当前COR的使用前提是

1 处理请求者如果无法确定请求内容.

2 需要将请求处理机制和请求内容解耦,才会使用CoR

根据你的测试代码加上BANQ上的测试代码的话估计1 2前提是有的。

但是客户端应该不应该去维护这个链的关系和分配责任。

事实上客户端调用到底是什么样的我还是很糊涂...可能是经验不到。望大家给予指点。。谢谢楼上回复

freebox
2008-09-17 08:04
init是由配置决定的,可以注入进去,因为省略了配置所以才写在init里,实际应用时客户端是看不到它的。甚至可以只声明接口为public,其它环声明成包访问级别,客户端根本就得不到其它的引用。

class Client{

private Manager first;

public void setManager(Manager manager){

this.first=manager;

}

public void test(){

first.manageIt(200);

}

}

环的构成用注入,Client的第一个环也注入。

[该贴被freebox于2008-09-17 08:11修改过]

ITfuture
2008-09-17 09:00
谢谢你的解释.我似乎了解了...呵呵。感觉自己有点钻牛角尖,没有彻底想透一个链的本质.

在回头看BANQ的代码。他将链的责任和处理分别划分到

HANDLER和REQUEST。

这样在增加一种链处理的时候。客户端完全不需要知道。并且不需要改动代码。只需要重新理清链之间的关系就可以。

谢谢FREEBOX。谢谢你的无私。哈哈

不知道我理解的是否正确?

猜你喜欢
2Go 1 2 下一页