Design Pattern: Mediator Pattern in Go

Mediator pattern centralizes the communication among objects, so that objects communicate through a mediator instead of direct communication. This way the objects do not need to worry about the logic for communicating with each other.

Mediator Pattern communication Between the Mediator and Colleagues

This article demonstrates Mediator pattern implementations in Go. Check the implementation details and examples.

Implementation

Use the following steps to implement Mediator pattern in Golang.

  • Create a mediator interface. Declare methods required for communication between objects.
  • Define a mediator struct and implement the mediator interface.
  • Create colleague interface and main colleague struct. Declare a field for storing a mediator in the colleague struct.
  • Create multiple colleague structs. Embed the main colleague struct and implement the colleague interface for the colleague structs.
  • While initiating new colleague pass and set the mediator and the mediator can be used to communicate to other colleague objects.

Examples

Let’s take a look at a few examples of Mediator pattern implementation in Golang-

Example #1: General Mediator

Here is a general example of Mediator pattern.

Mediator Interface

  • Create file “imediator.go”.
  • Define interface “IMediator”.
  • Declare method “SendMessage”. This takes a colleague and a string message as param.
// imediator.go

package main

type IMediator interface {
	SendMessage(colleague Colleague, msg string)
}

Mediator Struct

  • Create file “mediator.go”.
  • Define struct “Mediator”.
  • Create method “NewMediator”. This method initiates a new “Mediator” and returns that.
  • Implement interface “IMediator”. Define method “SendMessage”, this accepts an “IColleague” and message. Then the method calls the “ReceiveMesage” of the colleague.
// mediator.go

package main

type Mediator struct {
}

func NewMediator() (mediator *Mediator) {
	mediator = &Mediator{}
	return
}

func (mediator *Mediator) SendMessage(receiver IColleague, msg string) {
	receiver.ReceiveMessage(msg)
}

Colleague Struct

  • Create file “colleague.go”.
  • Define interface “IColleague”.
  • Declare methods “ReceiveMessage” and “SendMessage” for the interface.
  • Create struct “Colleague”. This is the main colleague struct.
  • Define a field named “mediator”, of type “Mediator” (pointer).
  • Define the method “NewColleague”, which works as a constructor. This method also accepts a “Mediator” and stores that in struct “mediator” field.
// colleague.go

package main

type IColleague interface {
	ReceiveMessage(message string)
	SendMessage(colleague IColleague, message string)
}

type Colleague struct {
	mediator *Mediator
}

func NewColleague(mediator *Mediator) (colleague *Colleague) {
	colleague = &Colleague{}
	colleague.mediator = mediator
	return
}

Colleague1 Struct

  • Create file “colleague1.go”.
  • Define struct “Colleague1”.
  • Embed the struct “Colleague” into it.
  • Define method “NewColleague1”. This initiates a new “Colleague1”, and sets the embedded “Colleague” with a new “Colleague”(using the “NewColleague” method).
  • Implement the “IColleague” interface. Define methods “ReceiveMessage” and “SendMessage” for the interface implementation. 
  • In the “SendMessage” method implementation, call the “SendMessage” from the mediator.
// colleague1.go

package main

import "fmt"


type Colleague1 struct {
	*Colleague
}

func NewColleague1(mediator *Mediator) (colleague1 *Colleague1) {
	colleague1 = &Colleague1{}
	colleague1.Colleague = NewColleague(mediator)
	return
}

func (colleague1 *Colleague1) ReceiveMessage(msg string) {
	fmt.Printf("Message received in Colleague1: %s\n",  msg)
}

func (colleague1 *Colleague1) SendMessage(colleague IColleague, msg string) {
	colleague1.mediator.SendMessage(colleague, msg)
}

Colleague2 Struct

  • Create file “colleague2.go”.
  • Define struct “Colleague2”. Embed the struct “Colleague” into it.
  • Implement interface “IColleague” interface for the struct.
// colleague2.go

package main

import "fmt"


type Colleague2 struct {
	*Colleague
}

func NewColleague2(mediator *Mediator) (colleague2 *Colleague2) {
	colleague2 = &Colleague2{}
	colleague2.Colleague = NewColleague(mediator)
	return
}

func (colleague2 *Colleague2) ReceiveMessage(msg string) {
	fmt.Printf("Message received in Colleague2: %s\n",  msg)
}

func (colleague2 *Colleague2) SendMessage(colleague IColleague, msg string) {
	colleague2.mediator.SendMessage(colleague, msg)
}

Colleague3 Struct

  • Create file “colleague2.go”.
  • Define struct “Colleague3” and embed the “Colleague” struct into it.
  • Implement interface “IColleague” interface for the struct.
// colleague3.go

package main

import "fmt"

type Colleague3 struct {
	*Colleague
}

func NewColleague3(mediator *Mediator) (colleague3 *Colleague3) {
	colleague3 = &Colleague3{}
	colleague3.Colleague = NewColleague(mediator)
	return
}

func (colleague3 *Colleague3) ReceiveMessage(msg string) {
	fmt.Printf("Message received in Colleague3: %s\n",  msg)
}

func (colleague3 *Colleague3) SendMessage(colleague IColleague, msg string) {
	colleague3.mediator.SendMessage(colleague, msg)
}

Demo

To use the implementation create a new “Meditor”, Then create new colleagues.

To send message from on colleague to another, call the “SendMessage” method of one colleague and pass another colleague to that.

// main.go

package main

func main() {
	mediator := NewMediator()
	colleague1 := NewColleague1(mediator)
	colleague2 := NewColleague2(mediator)
	colleague3 := NewColleague3(mediator)

	colleague1.SendMessage(colleague2, "message from colleague1")
	colleague1.SendMessage(colleague3, "message from colleague1")

	colleague2.SendMessage(colleague3, "message from colleague2")
	colleague3.SendMessage(colleague1, "message from colleague3")
}

Output

Following output will be generated.

Message received in Colleague2: message from colleague1
Message received in Colleague3: message from colleague1
Message received in Colleague3: message from colleague2
Message received in Colleague1: message from colleague3

Source Code

Use the following link to get the source code:

Other Code Implementations

Use the following links to check Mediator pattern implementation in other programming languages.

Leave a Comment


The reCAPTCHA verification period has expired. Please reload the page.