Skip to content

Instantly share code, notes, and snippets.

@maplemap
Forked from DmitriiNazimov/pattern-mediator.js
Created July 19, 2020 09:27
Show Gist options
  • Save maplemap/1287682793f9123cb05e3d834b0818a9 to your computer and use it in GitHub Desktop.
Save maplemap/1287682793f9123cb05e3d834b0818a9 to your computer and use it in GitHub Desktop.
[JS ES6 Паттерн ПОСРЕДНИК (mediator) ] #js #ES6 #ООП #Паттерны
/**
*
* ПАТТЕРН ПОСРЕДНИК (mediator)
*
* Паттерн ПОСРЕДНИК (mediator) - это поведенческий паттерн проектирования, который позволяет уменьшить связанность
* множества классов между собой, благодаря перемещению этих связей в один класс-посредник.
* Паттерн Посредник используется для централизации сложных взаимодействий и управляющих операций между объектами.
* Один из модулей медиатора изменяет состояние -> оповещает об этом медиатор -> медиатор оповещает об этом другие
* модули, которым положено знать о случившемся.
* Довольно популярна реализация Посредника при помощи Наблюдателя. При этом объект посредника будет выступать
* издателем, а все остальные компоненты станут подписчиками и смогут динамически следить за событиями, происходящими
* в посреднике. В этом случае трудно понять, чем же отличаются оба паттерна.
* Но Посредник имеет и другие реализации, когда отдельные компоненты жёстко привязаны к объекту посредника.
* Такой код вряд ли будет напоминать Наблюдателя, но всё же останется Посредником.
* Напротив, в случае реализации посредника с помощью Наблюдателя представим такую программу, в которой каждый компонент
* системы становится издателем. Компоненты могут подписываться друг на друга, в то же время не привязываясь к
* конкретным классам. Программа будет состоять из целой сети Наблюдателей, не имея центрального объекта-Посредника.
*
*/
// Mediator
class ChatRoom {
showMessage(user, message) {
const time = new Date()
const sender = user.getName()
console.log(time + '[' + sender + ']:' + message)
}
}
class User {
constructor(name, chatMediator) {
this.name = name
this.chatMediator = chatMediator
}
getName() {
return this.name
}
send(message) {
this.chatMediator.showMessage(this, message)
}
}
const mediator = new ChatRoom()
const john = new User('John Doe', mediator)
const jane = new User('Jane Doe', mediator)
john.send('Hi there!')
jane.send('Hey!')
// Output will be
// Feb 14, 10:58 [John]: Hi there!
// Feb 14, 10:58 [Jane]: Hey!
//Более сложный вариант, тут соблюдены все формальности данного паттерна, но он получился чересчур абстрактным и громоздким
class Mediator {
constructor() {
}
ColleagueChanged(colleague) {
}
}
class ConcreteMediator extends Mediator {
constructor() {
super()
console.log('ConcreteMediator created')
this.colleague1 = new ConcreteColleague1(this)
this.colleague2 = new ConcreteColleague2(this)
}
ColleagueChanged(colleague) {
switch(colleague) {
case this.colleague1:
console.log('ConcreteColleague1 has Changed -> change ConcreteColleague2.feature: ')
this.colleague2.setFeature('new feature 2');
break;
case this.colleague2:
console.log('ConcreteColleague2 has Changed, but do nothing')
break
default:
console.log('Do nothing')
}
}
}
class Colleague {
constructor() {
}
Changed() {
this.mediator.ColleagueChanged(this)
}
}
class ConcreteColleague1 extends Colleague {
constructor(mediator) {
super()
console.log('ConcreteColleague1 created')
this.mediator = mediator
this.feature = "feature 1"
}
setFeature(feature) {
console.log('ConcreteColleague1 Feature has changed from ' + this.feature + ' to ' + feature)
this.feature = feature
this.Changed()
}
}
class ConcreteColleague2 extends Colleague {
constructor(mediator) {
super()
console.log('ConcreteColleague2 created')
this.mediator = mediator
this.feature = "feature 2"
}
setFeature(feature) {
console.log('ConcreteColleague2 Feature has changed from ' + this.feature + ' to ' + feature)
this.feature = feature
this.Changed()
}
}
function init_Mediator() {
var mediator = new ConcreteMediator();
mediator.colleague1.setFeature("new feature 1");
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment