20-观察者(Observer)模式Ruby实现

Posted 架构设计模式

tags:

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

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

关键字Gof 23 设计模式 观察者模式  Ruby

Observer Pattern basedon Ruby

REN gang

Abstract:This paper gives a scene example to describe theuse of Observer 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; Observer Pattern  Ruby

 

1. 标准定义

观察者(Observer)模式标准定义:定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时, 所有依赖于它的对象都得到通知并被自动更新。

2. 分析和说明

观察者(Observer)模式属于对象行为型模式。观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态上发生变化时,会通知所有观察者对象,使他们能够自动更新自己。这一模式中主要针对两个对象objectObserver。一个object可以有多个Observer,当—个object对象的状态发生改变时,所有依赖于它的Observer对象都得到通知被自动更新。

观察者(Observer)模式结构如图1所示,其角色包括抽象主题(Subject)角色、抽象观察者(Observer)角色、具体主题(Concrete Subject)角色和具体观察者(Concrete Observer)角色。

 

1 观察者模式结构

    抽象主题(Subject)角色:主题角色把所有对观察对象的引用保存在此聚集里,每个主题都可以有任何数量的观察者。抽象主题提供一个接口,可以增加和删除观察者对象,主题角色又叫做抽象被观察者(Observable)角色,一般用一个抽象类或者一个接口实现。

    抽象观察者(Observer)角色:为所有具体观察者定义一个接口,在得到主题的通知时更新自己。这个接口叫做更新接口。抽象观察者角色一般用一个抽象类或者一个接口实现,在这个示意性的实现中,更新接口只包含一个方法(即update()方法),这个方法叫做更新方法。

    具体主题(Concrete Subject)角色:将有关状态存主具体观察者对象;在具体主题的内部状态改变时,给所有登记过的观察者发出通知。具体主题角色又叫做具体被观察者角色(Concrete Observable)。具体主题角色负责实现对观察者引用的聚集的管理方法。

    具体观察者(Concrete Observer)角色:存储与主题的状态自恰的状态。具体观察者角色实现抽象观察者角色所要求的更新接口,以便使本身的状态与主题的状态相协调。如果需要,具体观察者角色可以保存一个指向具体主题对象的引用。具体观察者角色通常用一个具体子类实现。

3 应用场景举例

比如公司的通讯录是大家都要使用的,同时也是经常变化的。每次通讯录的变化,都要把这些更新后的通讯录发布给所有的公司员工。这就可以采用观察者模式。

在这里可以把AbstractAddressBook抽象类理解为抽象主题(Subject)角色。AbstractEmployee抽象类是抽象观察者(Observer)角色。CompanyAddressBook类是具体主题(Concrete Subject)角色。CompanyEmployee类是具体观察者(Concrete Observer)角色。其结构类图如图2所示。CompanyAddressBook类继承AbstractAddressBook抽象类,CompanyEmployee类继承AbstractEmployee抽象类。AbstractEmployee抽象类关联AbstractAddressBook抽象类,即AbstractEmployee类有AbstractAddressBook类的属性。


2 观察者模式类图

 

4Ruby的实现程序代码

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

程序代码清单

 

 

#!/behavioralpatterns/observer

 

class AbstractEmployee

 

       def  initialize()

       @addressBook = nil

         @addressBookContents = nil

     end

      

       def  getAddressBook

              @addressBook

       end

 

       def  setAddressBook(addressBook)

              @addressBook  = addressBook;

       end

      

       def  superUpdate(book)

              setAddressBook(book)

              @addressBookContents  = @addressBook.getAddressBook        

       end  

end

 

class AbstractAddressBook

      

       def  initialize()

       @employeeList  = Array.new

         @addressBook = nil

     end

             

       def  getAddressBook

              @addressBook

       end

 

       def  setAddressBook(addressBook)

              @addressBook  = addressBook

       end

      

       def  superAddEmployee(employee)

              @employeeList<<  employee

       end

      

       def  removeEmployee(employee)

              @employeeList.delete(employee)

       end

      

       def  notice

       end

end       

             

class CompanyEmployee <  AbstractEmployee   

 

     def CompanyEmployee(employeeName)

              #super();

              @employeeName  = employeeName

       end

      

       def  getEmployeeName()

              @employeeName;

       end

 

       def  setEmployeeName(employeeName)

              @employeeName  = employeeName

       end

      

       def  update( book ) 

              superUpdate(book)

              puts  getEmployeeName()+"更新通讯录。"+"通讯录内容:"+@addressBookContents

       end        

end

 

class CompanyAddressBook <  AbstractAddressBook

 

       def  CompanyAddressBook

              @addressBook  = "旧的通信录"

       end

      

       def  addEmployee(employee)              

              employee.update(self);

              superAddEmployee(employee)

       end

 

       def  notice

             

              for  employee in @employeeList do    

                  employee.update(self)                 

              end        

       end

end

 

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

 

puts "——————原有的通讯录——————"

addressBook = CompanyAddressBook.new

addressBook.CompanyAddressBook

             

employee1 = CompanyEmployee.new

employee1.CompanyEmployee("employee1")

employee2 = CompanyEmployee.new

employee2.CompanyEmployee("employee2")

             

addressBook.addEmployee(employee1)

addressBook.addEmployee(employee2)

             

puts "——————更新的通讯录——————"

newAddressBook = "新的通讯录"

addressBook.setAddressBook(newAddressBook)

             

addressBook.notice()

 

BEGIN {

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

}

 

END {

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

}

 

 

观察者模式测试类输出结果如下所示:

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

——————原有的通讯录——————

mployee1更新通讯录。通讯录内容:旧的通信录

mployee2更新通讯录。通讯录内容:旧的通信录

——————更新的通讯录——————

mployee1更新通讯录。通讯录内容:新的通讯录

mployee2更新通讯录。通讯录内容:新的通讯录

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

 

参考文献

[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



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

RxJava系列2(基本概念及使用介绍)

Java中使用Observer接口和Observable类实践Observer观察者模式

用Delphi实现观察者模式(Observer模式)

JDK自带的Observable和Observer实现观察者模式

观察者模式

20.观察者模式