Mediator

2022. 3. 22. 00:00CSharp/Design Pattern

반응형

개체 간의 혼란스러운 종속성을 줄일 수 있는 행동 디자인 패턴

개체 간의 직접 통신을 제한하고 중재자 개체를 통해서만 협력하도록 합니다.

이를 통해 통신 객체 간 의존성을 줄일 수 있으므로 결합도를 감소시킨다.

 

문제점

항공기들이 동시에 하나의 공항으로 들어오고 있다고 가정하자.

각 항공기들이 서로 무선 통신을 하여 누가 먼저 착륙할지를 정한다면

불필요한 혼선만 일어날 것이고 잘못하면 사고로 이어질 수도 있다. 

 

 

 

해결책

각 항공기,헬기, 경비행기 등등은 서로 통신하지 않고 컨트롤 타워 하고만 통신을 한다.

컨트롤 타워는 전체 비행을 제어할 필요는 없고 누가 착륙하고 이륙할 지만  정하면 된다.

 

 

class diagram

https://refactoring.guru/design-patterns/mediator

 

 

ComponentA~D

: mediator 의 참조를 가지고 있는 비즈니스 논리를 포함하는 다양한 클래스

 

Mediator (interface)

: 일반적으로 단일 알림 방법을 포함하는 구성 요소와의 통신 방법을 선언

 

ConcreateMediator

: 다양한 구성 요소 간의 관계를 캡슐화. 자신이 관리하는 모든 구성요소에 대한 참조를 유지하고

때로는 수명주기를 관리하기도 한다. 

 

적용

  • 다른 클래스와 밀접하게 연결되어 있어 일부 클래스를 변경하기 어려울 때
  • 다른 구성 요소에 너무 의존하기 때문에 다른 프로그램에서 구성 요소를 재사용할 수 없는 경우
  • 다양한 컨텍스트에서 몇 가지 기본 동작을 재사용하기 위해 수많은 하위 클래스를 만들어야 할때

 

간단한 chatting 을  예로 구현해 보겠다.

/// <summary>
/// mediator interface
/// </summary>
public interface IChatRoom
{
    void Register(IUser participant);
    void Send(string from, string to, string message);
}


/// <summary>
/// The 'ConcreteMediator' class
/// </summary>
public class Chatroom : IChatRoom
{
    private Dictionary<string, IUser> participants = new Dictionary<string, IUser>();
    public void Register(IUser participant)
    {
        if (!participants.ContainsValue(participant))
        {
            participants[participant.Name] = participant;
        }
        participant.Chatroom = this;
    }
    public void Send(string from, string to, string message)
    {
        IUser participant = participants[to];
        if (participant != null)
        {
            participant.Receive(from, message);
        }
    }
}

/// <summary>
/// IUser Component
/// </summary>
public interface IUser
{
    IChatRoom Chatroom { get; set; }
    string Name { get; }

    void Receive(string from, string message);
    void Send(string to, string message);
}


public abstract class User : IUser
{
    private readonly string _name;
    // Constructor
    public User(string name)
    {
        _name = name;
    }

    public string Name
    {
        get { return _name; }
    }

    public IChatRoom Chatroom { get; set; }

    public void Send(string to, string message)
    {
        Chatroom.Send(_name, to, message);
    }

    public virtual void Receive(string from, string message)
    {
        Console.WriteLine("{0} to {1}: '{2}'",
            from, Name, message);
    }
}

public class Couple : User
{
    // Constructor
    public Couple(string name)
        : base(name)
    {
    }
    public override void Receive(string from, string message)
    {
        Console.Write("To a Couple: ");
        base.Receive(from, message);
    }
}

public class Solo : User
{
    // Constructor
    public Solo(string name)
        : base(name)
    {
    }
    public override void Receive(string from, string message)
    {
        Console.Write("To a Solo: ");
        base.Receive(from, message);
    }
}

사용법

IChatRoom chatroom = new Chatroom();
IUser leejin = new Couple("이진");
IUser heedo = new Couple("희도");
IUser yurim = new Couple("유림");
IUser jiyong = new Couple("지용");
IUser seunghwan = new Solo("승환");
chatroom.Register(leejin);
chatroom.Register(heedo);
chatroom.Register(yurim);
chatroom.Register(jiyong);
chatroom.Register(seunghwan);
leejin.Send("희도", "안녕 희도야");
yurim.Send("지용", "뭐해?");
jiyong.Send("유림", "승환이랑 있어");
jiyong.Send("승환", "야 심심하다");
seunghwan.Send("이진", "안녕하세요 선배님");
heedo.Send("이진", "안녕 이진");
// output
To a Couple: 이진 to 희도: '안녕 희도야'
To a Couple: 유림 to 지용: '뭐해?'
To a Couple: 지용 to 유림: '승환이랑 있어'
To a Solo: 지용 to 승환: '야 심심하다'
To a Couple: 승환 to 이진: '안녕하세요 선배님'
To a Couple: 희도 to 이진: '안녕 이진'

 

 

관련영상

https://youtu.be/-ryKk5W_rAc

 

 

반응형

'CSharp > Design Pattern' 카테고리의 다른 글

Strategy (전략패턴)  (0) 2022.03.24
Observer  (0) 2022.03.23
Command  (0) 2022.03.21
Template Method  (0) 2022.03.18
State  (0) 2022.03.17