Skip to content

Instantly share code, notes, and snippets.

@OleksandrPoltavets
Last active March 29, 2024 13:19
Show Gist options
  • Save OleksandrPoltavets/e8392e344055865dd24c94628476d33c to your computer and use it in GitHub Desktop.
Save OleksandrPoltavets/e8392e344055865dd24c94628476d33c to your computer and use it in GitHub Desktop.

Коротке пояснення:

Посередник (Mediator, Intermediary, Controller) — це поведінковий патерн проектування, що дає змогу зменшити зв’язаність великої кількості класів між собою, завдяки переміщенню цих зв’язків до одного класу-посередника.

Плюси та мінуси:

Плюси:

  • Усуває залежності між компонентами, дозволяючи використовувати їх повторно.
  • Спрощує взаємодію між компонентами.
  • Централізує керування в одному місці.

Мінуси:

  • Посередник може сильно «роздутися/розростися».

Приклад коду:

class Mediator
  def notify(sender, event)
    if sender == 'ComponentA'
      puts "Mediator received #{event} from ComponentA."
      process_event_a(event)
    elsif sender == 'ComponentB'
      puts "Mediator received #{event} from ComponentB."
      process_event_b(event)
    end
  end

  private

  def process_event_a(event)
    puts "Mediator processes #{event} and decides to update ComponentB accordingly."
    # Imagine this triggers some update in ComponentB, without directly calling its methods here.
  end

  def process_event_b(event)
    puts "Mediator processes #{event} and decides to inform ComponentA about changes."
    # Here, the mediator could inform ComponentA about something, without direct method calls.
  end
end

class BaseComponent
  attr_accessor :mediator

  def initialize(mediator = nil)
    @mediator = mediator
  end
end

class ComponentA < BaseComponent
  def send_event
    event = "EventA"
    puts 'ComponentA sends EventA to the Mediator.'
    @mediator.notify(self.class.name, event) if @mediator
  end
end

class ComponentB < BaseComponent
  def send_event
    event = "EventB"
    puts 'ComponentB sends EventB to the Mediator.'
    @mediator.notify(self.class.name, event) if @mediator
  end
end

# Клієнтський код
mediator = Mediator.new
component_a = ComponentA.new(mediator)
component_b = ComponentB.new(mediator)

component_a.send_event
# => ComponentA sends EventA to the Mediator.
# => Mediator received EventA from ComponentA.
# => Mediator processes EventA and decides to update ComponentB accordingly.

component_b.send_event
# => ComponentB sends EventB to the Mediator.
# => Mediator received EventB from ComponentB.
# => Mediator processes EventB and decides to inform ComponentA about changes.

У цьому прикладі, Mediator координує дії між двома компонентами (ComponentA та ComponentB), уникнути прямого зв'язку між ними. Компоненти спілкуються з посередником замість того, щоб спілкуватися один з одним напряму, що дозволяє зменшити зв'язаність між компонентами системи. Коли відбувається подія в одному з компонентів, він повідомляє про це посередника, а той, в свою чергу, вирішує, як реагувати на цю подію, можливо, активуючи методи інших компонентів.

Аналогія у житті:

Аеропорт як місце, де пілоти (класи) повідомляють диспетчерську вежу (посередник) про свої наміри злетіти або приземлитись, а вежа координує ці дії, щоб запобігти зіткненням і забезпечити плавність руху, мінімізуючи прямий контакт між пілотами.

Аналогія у Ruby on Rails:

У Ruby on Rails аналогія з посередником (Mediator) може бути представлена як взаємодія між контролерами і моделями. Контролери виступають як посередники, які приймають запити від користувачів (через в'юхи), вирішують, які дані потрібні з моделей, і потім передають ці дані назад у в'юхи для відображення. Таким чином, контролери зменшують пряму залежність між в'юхами (представленням) та моделями (даними), організовуючи взаємодію між ними.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment