23-访问者(Visitor)模式Ruby实现

Posted 架构设计模式

tags:

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

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

关键字Gof 23 设计模式 访问者模式 Ruby

Visitor Pattern basedon Ruby

REN gang

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

Key word: Gof 23; DesignPattern; Visitor Pattern Ruby

 

1. 标准定义

访问者(Visitor)模式标准定义:表示一个作用于某对象结构中的各元素的操作。它使你可以在不改变各元素的类的前提下定义作用于这些元素的新操作。

2. 分析和说明

访问者(Visitor)模式属于对象行为型模式。访问者模式的目的是封装一些施加于某种数据结构元素之上的操作。一旦这些操作需要修改的话,接受这个操作的数据结构可以保持不变。访问者模式适用于数据结构相对未定的系统,它把数据结构和作用于结构上的操作之间的耦合解脱开,使得操作集合可以相对自由的演化。访问者模式使得增加新的操作变的很容易,就是增加一个新的访问者类。访问者模式将有关的行为集中到一个访问者对象中,而不是分散到一个个的节点类中。当使用访问者模式时,要将尽可能多的对象浏览逻辑放在访问者类中,而不是放到它的子类中。访问者模式可以跨过几个类的等级结构访问属于不同的等级结构的成员类。

访问者(Visitor)模式结构如图1所示,其角色包括抽象访问者(Visitor)角色、具体访问者(Concrete Visitor)角色、抽象节点(Node)角色、具体节点(Node)角色和结构对象(Object Structure)角色。

抽象访问者(Visitor)角色:声明了一个或者多个访问操作,形成所有的具体元素角色必须实现的接口。

    具体访问者(Concrete Visitor)角色:实现抽象访问者角色所声明的接口,也就是抽象访问者所声明的各个访问操作。

    抽象节点(Node)角色:声明一个接受操作,接受一个访问者对象作为一个参量。

    具体节点(Node)角色:实现了抽象元素所规定的接受操作。

    结构对象(Object Structure)角色:有如下的一些责任,可以遍历结构中的所有元素;如果需要,提供一个高层次的接口让访问者对象可以访问每一个元素;如果需要,可以设计成一个复合对象或者一个聚集,如列(List)或集合(Set)。 


1 访问者模式结构

   

3 应用场景举例

比如公司一般都要接受多方面的审查,对于工商部门,看看是否符合商务审计。对于税务部门,看看是否合法纳税。对于会计师事务所,要对公司进行财务审计。这些部门都是外部的参观者。抽象访问者(Visitor)角色:工商部门、税务部门和会计师事务所是具体访问者角色。定义一个抽象公司的抽象节点角色。不同的公司工商情况,税务情况和会计情况就是具体节点角色。

在这里可以把Visitor抽象类理解为抽象访问者(Visitor)角色。AccountingFirm类、TaxBureau类、TradeBureau类是具体访问者(Concrete Visitor)角色。AbstractCompany抽象类是抽象节点(Node)角色。CompanyA类和CompanyB类是具体节点(Node)角色。其结构类图如图2所示。AccountingFirm类、TaxBureau类、TradeBureau类继承Visitor抽象类,CompanyA类和CompanyB类继承AbstractCompany抽象类。AbstractCompany抽象类关联Visitor抽象类。

2 访问者模式类图

 

4Ruby的实现程序代码

Ruby程序实现主要包括Visitor抽象类,AbstractCompany抽象类,AccountingFirm类、TaxBureau类、TradeBureau类,CompanyA类和CompanyB类等7个类。其关系如图2所示。下面分别列出这7个类的程序代码,最后列出测试代码并显示输出结果。

程序代码清单

 

 

#!/behavioralpatterns/visitor

 

 class Visitor

      

        def VisitCompanyA(company)

        end

        

        def VisitCompanyB(company)

        end

        

end

 

class AbstractCompany

      

       def  Accept(vistor)

              @vistor  = vistor

       end

      

       def  doVisit

       end

end

 

class AccountingFirm < Visitor

      

       def  VisitCompanyA(company)

              puts  "CompanyA类公司进行会计审计工作"

       end

      

       def  VisitCompanyB(company)

               puts   "CompanyB类公司进行会计审计工作"

       end

end

 

class TaxBureau < Visitor

 

       def  VisitCompanyA(company)

              puts  "CompanyA类公司进行税务审计工作"

       end

      

       def  VisitCompanyB(company)

               puts "CompanyB类公司进行税务审计工作"

       end

end

 

class TradeBureau < Visitor

 

       def  VisitCompanyA(company)

              puts  "CompanyA类公司进行工商年审工作"

       end

      

       def  VisitCompanyB(company)

               puts "CompanyB类公司进行工商年审工作"

       end

end

 

class CompanyA < AbstractCompany

 

       def  VisitA

       end

      

       def  doVisit

              @vistor.VisitCompanyA(self)

       end

end

 

class CompanyB < AbstractCompany

 

       def  VisitB

       end

      

       def  doVisit

              @vistor.VisitCompanyB(self)

       end

end

      

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

 

company1 = CompanyA.new()

company2 = CompanyB.new()     

             

accountingFirm = AccountingFirm.new()

taxBureau = TaxBureau.new()

tradeBureau = TradeBureau.new()

             

puts "————对CompanyA类公司进行处理————"

company1.Accept(accountingFirm);           

company1.doVisit();

             

company1.Accept(taxBureau);            

company1.doVisit();     

             

company1.Accept(tradeBureau);         

company1.doVisit();     

      

puts

puts "————对CompanyB类公司进行处理————"

company2.Accept(accountingFirm);           

company2.doVisit();

             

company2.Accept(taxBureau);            

company2.doVisit();     

             

company2.Accept(tradeBureau);         

company2.doVisit();     

 

 

BEGIN {

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

}

 

END {

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

}

 

 

访问者模式测试类输出结果如下所示:

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

————对CompanyA类公司进行处理————

CompanyA类公司进行会计审计工作

CompanyA类公司进行税务审计工作

CompanyA类公司进行工商年审工作

 

————对CompanyB类公司进行处理————

CompanyB类公司进行会计审计工作

CompanyB类公司进行税务审计工作

CompanyB类公司进行工商年审工作

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

 

 

参考文献

[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



以上是关于23-访问者(Visitor)模式Ruby实现的主要内容,如果未能解决你的问题,请参考以下文章

GOF23设计模式之访问者模式(visitor)

23种设计模式之访问者模式(Visitor)

二十三种设计模式[23] - 访问者模式(Visitor Pattern)

JAVA设计模式(23):行为型-访问者模式(Visitor)

访问者模式(Visitor)

访问者模式(Visitor Pattern)