15-责任链(Chain of Responsibility)模式Ruby实现

Posted 架构设计模式

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了15-责任链(Chain of Responsibility)模式Ruby实现相关的知识,希望对你有一定的参考价值。

摘要:本文用一个实例场景描述Gof 23设计模式中的责任链模式,并用Ruby程序代码给予实现,同时也给出实现代码的UML模型。

关键字Gof 23 设计模式 责任链模式 Ruby

Chain ofResponsibility Pattern based on Ruby

REN gang

Abstract:This paper gives a scene example to describe theuse of Chain of Responsibility Pattern of Gof 23 Design Pattern, and achievesthe example by Ruby, at the same time, gives the UML model of realization ofthe example.

Key word: Gof 23; DesignPattern; Chain of Responsibility Pattern Ruby

 

1. 标准定义

责任链(Chain of Responsibility)模式标准定义:使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。

2. 分析和说明

责任链(Chain of Responsibility)模式属于行为型设计模式。在责任链模式中,各种服务组合或对象由没一个服务或对象对其下家的引用而接起来形成一个整体的系统链。请求在这个链上传递,直到链上的某一个对象决定处理此请求。客户并不知道链上的哪一个对象最终处理这个请求,系统可以在不影响客户端的情况下动态的重新组织链和分配责任。处理者有两个选择:承担责任或者把责任推给下家。一个请求可以最终不被任何接收端对象所接受。职责链可以提高系统的灵活性,通过配置多变的职责链可以完成系统功能的扩充或改变,保证系统的可移植性。

责任链(Chain of Responsibility)模式结构如图1所示,其角色包括抽象处理者(Handler)角色和具体处理者(Concrete Handler)角色。


1 责任链模式结构

    抽象处理者(Handler)角色:定义出一个处理请求的接口。如果需要,接口可以定义出一个方法,以设定和返回对下家的引用。这个角色通常由一个抽象类或者接口实现。图中的聚合关系给出了具体子类对下家的引用,抽象方法handleRequest()规范了子类处理请求的操作。

    具体处理者(Concrete Handler)角色:具体处理者接到请求后,可以选择将请求处理掉,或者将请求传给下家。由于具体处理者持有对下家的引用,因此,如果需要,具体处理者可以访问下家。

2 应用场景举例

比如公司技术部门有几位技术高手,当菜鸟在工作中遇到了问题,于是向这些高手们请教,如果第一位高手能解决问题,那这个过程就结束,否则传递给下一个高手,下一个高手也是同样操作,不能解决问题就再交给下下一位。这样,要么这些高手里其中一个能解决问题,要么这些高手全都不能解决这个问题,这就是责任链模式。

在这里可以把AbstractSuperMan抽象类理解为抽象处理者(Handler)角色。SuperManOne类,SuperManTwo类和SuperManThree类是具体处理者(Concrete Handler)角色。其结构类图如图2所示。SuperManOne类,SuperManTwo类和SuperManThree类继承AbstractSuperMan抽象类。AbstractSuperMan抽象类进行自我关联。


2 责任链模式类图

 

3Ruby的实现程序代码

Ruby程序实现主要包括AbstractSuperMan抽象类,PrimaryMan类,SuperManOne类,SuperManTwo类和SuperManThree类等5个类。其关系如图2所示。下面分别列出这5个类的程序代码,最后列出测试代码并显示输出结果。

程序代码清单

 

 

#!/behavioralpatterns/chainofresponsibility

 

class AbstractSuperMan    

      

       def  initialize()

         @answer = nil

         @successorSuperMan = nil       

     end

             

       def  getAnswer()

              @answer

       end

      

       def  setAnswer(answer)

              @answer  = answer

       end

      

       def  getSuccessorSuperMan()

              @successorSuperMan

       end

 

       def  setSuccessorSuperMan(successorSuperMan)

              @successorSuperMan  = successorSuperMan

       end

      

       def  answerTheQuestion(man)

       end

  

end

 

class PrimaryMan

      

       @@thisAnswer  = nil  

       def  question(answer)

              if  @@thisAnswer == answer

                true

              else

                false

              end        

       end

 

       def  getThisAnswer()

              @@thisAnswer

       end

 

       def  setThisAnswer(thisAnswer)

              @@thisAnswer  = thisAnswer;

       end

end

 

class SuperManOne < AbstractSuperMan

 

       @@isAnswer  = false

 

       def  answerTheQuestion(man)

              if  man.question(@answer)

                     puts  "SuperManOne回答正确。"

              else  

                     if  @@isAnswer

                            puts  "大家都不能回答这个问题。"

                     else  

                            @@isAnswer  = true;

                            if  @successorSuperMan != nil

                                   puts  "SuperManOne不会回答问题,提交下一个。"

                                   @successorSuperMan.answerTheQuestion(man)

                            end

                     end

              end

       end

end

 

 

class SuperManTwo < AbstractSuperMan

 

       @@isAnswer  = false

       def  answerTheQuestion(man)

              if  man.question(@answer)

                     puts  "SuperManOne回答正确。"

              else  

                     if  @@isAnswer

                            puts  "大家都不能回答这个问题。"

                     else  

                            @@isAnswer  = true;

                            if  @successorSuperMan != nil

                                   puts  "SuperManTwo不会回答问题,提交下一个。"

                                   @successorSuperMan.answerTheQuestion(man)

                            end

                     end

              end

       end

end

 

class SuperManThree < AbstractSuperMan  

 

       @@isAnswer  = false

       def  answerTheQuestion(man)

              if  man.question(@answer)

                     puts  "SuperManThree回答正确。"

              else  

                     if  @@isAnswer

                            puts  "大家都不能回答这个问题。"

                     else  

                            @@isAnswer  = true;

                            if  @successorSuperMan != nil

                                   puts  "SuperManThree不会回答问题,提交下一个。"

                                   @successorSuperMan.answerTheQuestion(man)

                            end

                     end

              end

       end

end

 

 

# ————————main主程序应用————————

 

superMan1 =  SuperManOne.new

superMan2 =  SuperManTwo.new

superMan3 =  SuperManThree.new

             

#形成一个闭环的链

superMan1.setSuccessorSuperMan(superMan2)

superMan2.setSuccessorSuperMan(superMan3)

superMan3.setSuccessorSuperMan(superMan1)

             

#设置提问者的问题和答案

primaryMan = PrimaryMan.new

primaryMan.setThisAnswer("ANSWER");

             

#superMan1能回答这个答案

#superMan1.setAnswer("ANSWER");

             

#superMan2能回答这个答案

#superMan2.setAnswer("ANSWER");

             

#superMan3能回答这个答案

superMan3.setAnswer("ANSWER");

superMan1.answerTheQuestion(primaryMan);

 

BEGIN {

    puts "———这是chainofresponsibility的输出开始———"

}

 

END {

    puts "———这是chainofresponsibility的输出结束———"

}

 

责任链模式测试类输出结果如下所示:

———这是chainofresponsibility的输出开始———

SuperManOne不会回答问题,提交下一个。

SuperManTwo不会回答问题,提交下一个。

SuperManThree回答正确。

———这是chainofresponsibility的输出结束———

 

 

参考文献

[1] E.Gamma, R.Helm, R.Johnson, andVlissides. Design Patterns Elements of Reusable Object Oriented Software. Addison-Wesley,1995

[2] E.Gamma, R.Helm, R.Johnson, andVlissides.著,李英军等译,设计模式:可复用面向对象软件的基础,北京:机械工业出版社.20009

[3] (日)高桥征义,(日)后藤裕藏 著,何文斯 译,Ruby基础教程(第4版),北京:人民邮电出版社.2014.09

[4] 许勇 等编著,Ruby on Rails 程序设计 深入剖析与范例应用,北京:清华大学出版社.2013.07

[5] (美)梅茨 著,张雪平,彭晓东译,面向对象设计实践指南:Ruby语言描述,北京:人民邮电出版社.2014.01

[6] Ruby官方网站:www.ruby-lang.org

[7] Ruby教程 http://www.runoob.com/ruby/ruby-tutorial.html


以上是关于15-责任链(Chain of Responsibility)模式Ruby实现的主要内容,如果未能解决你的问题,请参考以下文章

责任链模式(Chain of Responsibility Pattern)

责任链模式(chain of responsbility)

责任链模式(Chain of Responsibility Pattern)

责任链模式(Chain of Responsibility)

责任链模式(Chain of Responsibility)

责任链模式(chain of responsibility)