NOTE
Mediator Pattern
Mediator-pattern notes with UML, a Java department example, and a Go computer-component example.
This is a historical learning note and may contain outdated or incomplete understanding.
1. Definition
Suitable when interactions among multiple objects create excessive coupling, such as the controller in MVC.
2. UML
3. Java
3.1. Client
public class Client
{
public static void main(String[] args)
{
Mediator mediator = new Boss();
Dev dev = new Dev(mediator);
Finacial finacial = new Finacial(mediator);
dev.selfDo();
// Send a request through the mediator
dev.outDo("finacial");
}
}
3.2. Mediator
public interface Mediator
{
void register(String dname,Department d);
void command(String dname);
}
public class Boss implements Mediator
{
private Map<String, Department> map = new HashMap<>();
@Override
public void register(String dname, Department d)
{
map.put(dname, d);
}
@Override
public void command(String dname)
{
map.get(dname).selfDo();
}
}
3.3. Interacting Objects
public interface Department
{
void selfDo();
void outDo(String name);
}
public class Dev implements Department
{
private Mediator mediator;
public Dev(Mediator mediator)
{
this.mediator = mediator;
this.mediator.register("dev", this);
}
@Override
public void selfDo()
{
System.out.println("Develop project");
}
@Override
public void outDo(String name)
{
System.out.println("Development department needs funds");
mediator.command(name);
}
}
public class Finacial implements Department
{
private Mediator mediator;
public Finacial(Mediator mediator)
{
this.mediator = mediator;
this.mediator.register("finacial", this);
}
@Override
public void selfDo()
{
System.out.println("Finance department allocates funds");
}
@Override
public void outDo(String name)
{
System.out.println("Who needs funds?");
this.mediator.command(name);
}
}
4. Golang
4.1. Mediator
/* Mediator: the computer coordinates CDDriver, CPU, VideoCard, and SoundCard */
type Mediator struct {
CD *CDDriver
CPU *CPU
Video *VideoCard
Sound *SoundCard
}
// Singleton pattern
var mediator *Mediator
var once sync.Once
func GetMediatorInstance() *Mediator {
once.Do(func() {
mediator = &Mediator{}
})
return mediator
}
// The mediator coordinates interactions among components
func (m *Mediator) changed(i interface{}) {
switch inst := i.(type) {
case *CDDriver:
m.CPU.Process(inst.Data)
case *CPU:
m.Sound.Play(inst.Sound)
m.Video.Display(inst.Video)
}
}
4.2. Interacting Objects
/* CD drive reads data */
type CDDriver struct {
Data string
}
func (c *CDDriver) ReadData() {
c.Data = "music,image"
fmt.Printf("CDDriver: reading data %s\n", c.Data)
GetMediatorInstance().changed(c)
}
/* CPU separates the data into sound and video */
type CPU struct {
Video string
Sound string
}
func (c *CPU) Process(data string) {
sp := strings.Split(data, ",")
c.Sound = sp[0]
c.Video = sp[1]
fmt.Printf("CPU: split data with Sound %s, Video %s\n", c.Sound, c.Video)
GetMediatorInstance().changed(c)
}
/* Video card handles video */
type VideoCard struct {
Data string
}
func (v *VideoCard) Display(data string) {
v.Data = data
fmt.Printf("VideoCard: display %s\n", v.Data)
GetMediatorInstance().changed(v)
}
/* Sound card handles audio */
type SoundCard struct {
Data string
}
func (s *SoundCard) Play(data string) {
s.Data = data
fmt.Printf("SoundCard: play %s\n", s.Data)
GetMediatorInstance().changed(s)
}
4.3. Client
func main() {
mediator := mediator.GetMediatorInstance()
mediator.CD = &mediator.CDDriver{}
mediator.CPU = &mediator.CPU{}
mediator.Video = &mediator.VideoCard{}
mediator.Sound = &mediator.SoundCard{}
mediator.CD.ReadData()
}
Discussion
Sign in with GitHub to comment. Discussions are stored as GitHub Issues.View on GitHub