一根雪糕引发的危机

来源:互联网 发布:贪心算法最小生成树 编辑:程序博客网 时间:2024/04/25 22:00

    最近胃一直不好,往年夏天的时候就很少吃凉的,但是对于冰激凌之类的东西还是非常想吃的,今年吃了一次,感觉没事儿,于是就比较得瑟,有机会就吃一根,偶尔感觉不太舒服,忍忍也就过去了,前两天天气格外的热,再加上心情愉快,就各种得瑟,一次性吃了两个,于是,麻烦来了,各种肠胃炎,然后就各种买药、打针,胃总算好一点,但是由于病的时候身体比较虚弱,于是嗓子各种疼,各种咳嗽,头疼,虽然受了各种苦,但是今天突然想到这一连串反应不正是我们学过的一个设计模式——职责链模式吗?

我们的需求:

    如果我吃一个冰激凌,则胃疼,但是可以自愈;如果我吃两个,则会得肠胃炎,需要吃药打针;如果我吃三个,则需要输液;如果吃四个,就需要住院。

    如果把我的大脑当成一个对象,则吃冰激凌就是对象的请求,而职责需要在得病自愈——打针——输液——住院这一个职责链中传递。

    而且,如果我的体质并不是不变的,现在是这个状况,可能通过我一年的锻炼,到明年的时候,我可能吃两个冰激凌都不会有事,所以职责链就需要发生改变。这也是我们需要考虑的需求之一。

   下面我们来看职责链模式使多个对象都有机会处理请求,从而避免请求的发送者和接受者之间的耦合关系。将这个对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理他为止。

   职责链模式图:

我们的需求代码:

using System;// "Handler"abstract class Handler{  // Fields  protected Handler successor;   // Methods  public void SetSuccessor( Handler successor )  {    this.successor = successor;  }  abstract public void HandleRequest( int request );}// "ConcreteHandler1"class ConcreteHandler1 : Handler{  // Methods  override public void HandleRequest( int request )  {    if( request >= 0 && request < 10 )      Console.WriteLine("{0} handled request {1}",        this, request );    else      if( successor != null )      successor.HandleRequest( request );  }}// "ConcreteHandler2"class ConcreteHandler2 : Handler{  // Methods  override public void HandleRequest( int request )  {    if( request >= 10 && request < 20 )      Console.WriteLine("{0} handled request {1}",        this, request );    else      if( successor != null )      successor.HandleRequest( request );  }}// "ConcreteHandler3"class ConcreteHandler3 : Handler{  // Methods  override public void HandleRequest( int request )  {    if( request >= 20 && request < 30 )      Console.WriteLine("{0} handled request {1}",        this, request );    else      if( successor != null )      successor.HandleRequest( request );  }}/**//// <summary>/// Client test/// </summary>public class Client{  public static void Main( string[] args )  {    // Setup Chain of Responsibility    Handler h1 = new ConcreteHandler1();    Handler h2 = new ConcreteHandler2();    Handler h3 = new ConcreteHandler3();    h1.SetSuccessor(h2);    h2.SetSuccessor(h3);    // Generate and process request    int[] requests = { 2, 5, 14, 22, 18, 3, 27, 20 };    foreach( int request in requests )      h1.HandleRequest( request );  }}


 

职责链的优点: 

    1.从所举例子来看,首先降低了耦合度,把每一种情况的处理单独拿出来,如果需要修改的话可以单独进行修改,从而不影响其他代码。

    2.可简化对象之间的相互连接。

    3.增加给对象指派职责的灵活性:根据例子,如果身体状况出现改变,职责链的顺序已经个数可以随时发生改变

    4.增加新的请求处理类:如果要新增加或删除一个处理类,改动也会比较小。

职责链的缺点:

    让我们继续回到上面的例子,我们发现,其实当吃雪糕变成三个的时候,“自愈”和“吃药打针”其实没有做任何的事情,而只是做了一个传递工作。而传递工作之后,他们就成了垃圾对象。

    也就是说,他们在实际的处理中,并没有发挥任何的作用。那么当这个链结构比较长,比较复杂的话,会产生很多的内存垃圾对象。这也就是职责链的最大缺点之所在。

 

总结

其实,从上面所给例子中,我第一次想到的是状态模式,因为我每次吃完一个雪糕之后得到了一个状态,但是后来我发现状态模式没有职责链模式适合,最主要的原因,就是我认为职责链的灵活性,状态模式主要解决的是当控制一个对象状态转换条件表达式过于复杂时的情况,把状态的判断逻辑转移到表示不同状态的一系列类当中,可以把复杂的判断逻辑简化,也就是简单当前逻辑,所以状态模式的客户端是不会改变的,但是,从例子中我们可以看出,随着我的身体状态的改变,如果我身体变化了,状态模式的每一个状态类都需要修改,而如果使用职责链模式,则只需要改变客户端组链的方式,所以,职责链模式更适合这里。

最后,总结一句话,做人不能太得瑟了,珍惜好自己的身体。

 

原创粉丝点击