Spring SALE

Mediator in Ruby

Mediator is a behavioral design pattern that reduces coupling between components of a program by making them communicate indirectly, through a special mediator object.

The Mediator makes it easy to modify, extend and reuse individual components because they’re no longer dependent on the dozens of other classes.



Usage examples: The most popular usage of the Mediator pattern in Ruby code is facilitating communications between GUI components of an app. The synonym of the Mediator is the Controller part of MVC pattern.

Conceptual Example

This example illustrates the structure of the Mediator design pattern. It focuses on answering these questions:

  • What classes does it consist of?
  • What roles do these classes play?
  • In what way the elements of the pattern are related?

main.rb: Conceptual example

# The Mediator interface declares a method used by components to notify the
# mediator about various events. The Mediator may react to these events and pass
# the execution to other components.
class Mediator
  # @abstract
  # @param [Object] sender
  # @param [String] event
  def notify(_sender, _event)
    raise NotImplementedError, "#{self.class} has not implemented method '#{__method__}'"

class ConcreteMediator < Mediator
  # @param [Component1] component1
  # @param [Component2] component2
  def initialize(component1, component2)
    @component1 = component1
    @component1.mediator = self
    @component2 = component2
    @component2.mediator = self

  # @param [Object] sender
  # @param [String] event
  def notify(_sender, event)
    if event == 'A'
      puts 'Mediator reacts on A and triggers following operations:'
    elsif event == 'D'
      puts 'Mediator reacts on D and triggers following operations:'

# The Base Component provides the basic functionality of storing a mediator's
# instance inside component objects.
class BaseComponent
  # @return [Mediator]
  attr_accessor :mediator

  # @param [Mediator] mediator
  def initialize(mediator = nil)
    @mediator = mediator

# Concrete Components implement various functionality. They don't depend on
# other components. They also don't depend on any concrete mediator classes.
class Component1 < BaseComponent
  def do_a
    puts 'Component 1 does A.'
    @mediator.notify(self, 'A')

  def do_b
    puts 'Component 1 does B.'
    @mediator.notify(self, 'B')

class Component2 < BaseComponent
  def do_c
    puts 'Component 2 does C.'
    @mediator.notify(self, 'C')

  def do_d
    puts 'Component 2 does D.'
    @mediator.notify(self, 'D')

# The client code.
c1 = Component1.new
c2 = Component2.new
ConcreteMediator.new(c1, c2)

puts 'Client triggers operation A.'

puts "\n"

puts 'Client triggers operation D.'

output.txt: Execution result

Client triggers operation A.
Component 1 does A.
Mediator reacts on A and triggers following operations:
Component 2 does C.

Client triggers operation D.
Component 2 does D.
Mediator reacts on D and triggers following operations:
Component 1 does B.
Component 2 does C.

Mediator in Other Languages

Mediator in C# Mediator in C++ Mediator in Go Mediator in Java Mediator in PHP Mediator in Python Mediator in Rust Mediator in Swift Mediator in TypeScript