Behavior type: VIII Intermediary model

Time:2022-5-8

What is the mediation model

Mediator pattern is a behavior design pattern, which encapsulates a series of object interactions with a mediation object. Mediators make objects do not need to explicitly refer to each other, so that they are loosely coupled, and their interaction can be changed independently of each other.

Why use mediation mode

The mediator pattern recommends that you stop direct communication between components and make them independent of each other. These components must call a special mediator object, redirect the calling behavior through the mediator object, and cooperate in an indirect way. Ultimately, the component depends on only one mediator class and does not need to be coupled with multiple other components.

How to implement mediation mode

Here is an example of the train entering the station. The train can enter the station only when the platform is free, and the station dispatching is the intermediary. Each train communicates with the station dispatching (intermediary).

mediator. Go intermediary

package mediator

type mediator interface {
	canArrive(train) bool
	notifyAboutDeparture()
}

type stationManager struct {
	Platform free // platform free
	trainQueue     []train
}

func newStationManger() *stationManager {
	return &stationManager{
		isPlatformFree: true,
	}
}

func (s *stationManager) canArrive(t train) bool {
	if s.isPlatformFree {
		s.isPlatformFree = false
		return true
	}
	s.trainQueue = append(s.trainQueue, t)
	return false
}

func (s *stationManager) notifyAboutDeparture() {
	if !s.isPlatformFree {
		s.isPlatformFree = true
	}
	if len(s.trainQueue) > 0 {
		firstTrainInQueue := s.trainQueue[0]
		s.trainQueue = s.trainQueue[1:]
		firstTrainInQueue.permitArrival()
	}
}

train. Go train components

type train interface {
	Arrive() // arrival
	depart()
	permitArrival()
}

passenger_ train. Go passenger train

package mediator

import "fmt"

//Passenger train

type passengerTrain struct {
	mediator mediator
}

func (p *passengerTrain) arrive() {
	if !p.mediator.canArrive(p) {
		fmt. Println ("passenger train arrives, waiting for arrival")
		return
	}
	fmt. Println ("passenger train entry")
}

func (p *passengerTrain) depart() {
	fmt. Println ("passenger train departure")
	p.mediator.notifyAboutDeparture()
}

func (p *passengerTrain) permitArrival() {
	fmt. Println ("passenger trains are allowed to enter the station")
	p.arrive()
}

freight_ train. Go freight train

package mediator

import "fmt"

//Freight train

type freightTrain struct {
	mediator mediator
}

func (g *freightTrain) arrive() {
	if !g.mediator.canArrive(g) {
		fmt. Println ("freight train arrives, waiting for arrival")
		return
	}
	fmt. Println ("freight train inbound")
}

func (g *freightTrain) depart() {
	fmt. Println ("freight train departure")
	g.mediator.notifyAboutDeparture()
}

func (g *freightTrain) permitArrival() {
	fmt. Println ("freight trains are allowed to enter the station")
	g.arrive()
}

Call example

package mediator

func Example() {
	stationManager := newStationManger()

	passengerTrain := &passengerTrain{
		mediator: stationManager,
	}
	freightTrain := &freightTrain{
		mediator: stationManager,
	}

	passengerTrain.arrive()
	freightTrain.arrive()
	passengerTrain.depart()
}

//Passenger train entry
//The freight train arrived and waited for the arrival
//The passenger train leaves
//Freight trains are allowed to enter the station
//Freight train arrival

advantage

  1. Single responsibility principle. You can extract the communication between multiple components to the same location to make it easier to understand and maintain.
  2. Opening and closing principle. You can add new mediators without modifying the actual components.
  3. You can reduce the coupling between multiple components in the application.

shortcoming

  1. After a period of time, the mediator may evolve into the object of God.