vendredi 21 avril 2017

Chain of Responsibility Pattern in Ruby

I like Ruby and I'm learning design patterns. Here is an example of Chain Of Responsibility Pattern implementation. The domain model is as follows:

  • Element - a general interface of all members in chain. Each element can have a parent and children
  • Window, Menu, Button - elements of chain implementing Element interface
  • ClickHandler - it knows how to handle clicks and passed to elements

Here is my implementation:

class Element
  attr_reader :name, :parent, :children, :click_handler

  def initialize(name)
    @name = name
    @children = []
  end

  def set_parent(parent)
    @parent = parent
  end

  def add_child(child)
    child.set_parent self
    children << child
  end

  def set_click_handler(handler)
    @click_handler = handler
  end

  def click
    return click_handler.handle(self) if click_handler

    parent && parent.click
  end
end

class ClickHandler
  def handle(element)
    "Click on #{element.class.name}:#{element.name}"
  end
end

class Window < Element
end

class Menu < Element
end

class Button < Element
end

class Input < Element
end

Here how it can be used:

window = Window.new('App')                                                                                                 
menu = Menu.new('Main')                                                                                                    

open_file_button = Button.new('Open File')                                                                                 
menu.add_child(open_file_button)                                                                                           

window.add_child(menu)                                                                                                     

window.set_click_handler(ClickHandler.new)                                                                                 
menu.set_click_handler(ClickHandler.new)                                                                                   
open_file_button.set_click_handler(ClickHandler.new)                                                                       

open_file_button.click # => Click on Button:Open File

Have I understood this pattern?

Any thoughts are appreciated

Aucun commentaire:

Enregistrer un commentaire