[디자인패턴] 중재자 패턴 (Mediator Pattern)

koline·2023년 9월 7일
0

디자인패턴

목록 보기
18/24

중재자 패턴


객체 지향 설계에서 객체의 수가 너무 많아지면 구조가 복잡해져서 객체지향에서 가장 중요한 느슨한 결합의 특성을 해칠 수 있기 때문에 이를 해결하는 방법으로 서로 간 통신을 위해 중간에 이를 통제하고 지시할 수 있는 역할을 하는 중재자를 두고, 중재자에게 모든 것을 요구하여 통신의 빈도수를 줄여 상호 작용의 유연한 변경을 지원하고 객체 지향의 목표를 달성하게 해주는 패턴이다.

즉, 커뮤니케이션을 하고자 하는 객체가 있을 때 서로가 커뮤니케이션 하기 복잡한 경우 M:N의 관계에서 M:1의 관계로 복잡도를 떨어뜨려 이를 해결해주고 서로간 의사소통을 쉽게 해주고 커플링을 약화 시키며, 유지 보수 및 재사용의 확장성에 유리한 패턴이다.



구조


  1. Mediator: Colleague 객체 간의 상호참조를 위한 인터페이스. 클라이언트 등록, 실행 등의 메소드 정의
  2. Colleague: 다른 Colleague와의 상호참조를 위한 인터페이스.
  3. ConcreteMediator: Mediator 구현 클래스. Colleague 간의 상호참조를 조정
  4. ConcreteColleage: Colleague 구현 클래스. Mediator를 통해 다른 Colleague와의 상호참조



옵저버 패턴, 퍼사드 패턴과의 차이점


퍼사드 패턴

1통신을 위해 인터페이스를 설계하고 제공한다는 점에서 두 패턴은 동일하지만 퍼사드 패턴은 단방향 통신만 가능하지만 중재자 패턴은 양방향 통신을 지원합니다.

옵저버 패턴

옵저버 패턴은 1개의 publisher에 대해 N개의 subscriber가 존재하고 observer가 pulling이나 push 방식을 통해 관리하지만 중재자 패턴은 M개의 publisher와 N개의 subscriber 사이에서 1개의 mediator를 통해 통신을 하는 방식입니다.


구현


// Mediator.java (Mediator)
public interface Mediator {
    void addUser(User user);
    void removeUser(User user);
    void sendMessage(User user, String message);
}

// UserMessageMediator.java (ConcreteMediator)
public class UserMessageMediator implements Mediator {

    private List<User> userList = new ArrayList<>();

    @Override
    public void addUser(User user) {
        userList.add(user);
    }

    @Override
    public void removeUser(User user) {
        userList.remove(user);
    }

    @Override
    public void sendMessage(User user, String message) {
        for (User u : userList) {
            if (u != user) {
                u.receive(message);
            }
        }
    }
    
}

// User.java (Colleague)
public abstract class User {
    protected Mediator mediator;
    protected String name;

    public User(Mediator mediator, String name) {
        this.mediator = mediator;
        this.name = name;
    } 

    public abstract void receive(String message);
    public abstract void send(String message);
}

// ManUser.java (ConcreteColleague)
public class ManUser extends User {

    public ManUser(Mediator mediator, String name) {
        super(mediator, name);
    }

    @Override
    public void receive(String message) {
        System.out.println("[" + super.name + "] Message arrived: " + message);
    }

    @Override
    public void send(String message) {
        System.out.println("[" + super.name + "] Sent message");
        super.mediator.sendMessage(this, message);
    }
    
}

// WomanUser.java (ConcreteColleague)
public class WomanUser extends User {

    public WomanUser(Mediator mediator, String name) {
        super(mediator, name);
    }

    @Override
    public void receive(String message) {
        System.out.println("[" + super.name + "] Message arrived: " + message);
    }

    @Override
    public void send(String message) {
        System.out.println("[" + super.name + "] Sent message");
        super.mediator.sendMessage(this, message);
    }
    
}

// Client.java (Client)
public class Client {
    public static void main(String[] args) {
        Mediator mediator = new UserMessageMediator();

        User user1 = new ManUser(mediator, "Sonny");
        User user2 = new ManUser(mediator, "Jimin");
        User user3 = new WomanUser(mediator, "Minji");
        User user4 = new WomanUser(mediator, "Jenny");
        
        mediator.addUser(user1);
        mediator.addUser(user2);
        mediator.addUser(user3);
        mediator.addUser(user4);

        user1.send("어 나 프리미어리그 득점왕 손흥민인데");

        mediator.removeUser(user2);
        user3.send("어 나 뉴진스 민진데");
    }
}

// 실행 결과
[Sonny] Sent message
[Jimin] Message arrived: 어 나 프리미어리그 득점왕 손흥민인데
[Minji] Message arrived: 어 나 프리미어리그 득점왕 손흥민인데
[Jenny] Message arrived: 어 나 프리미어리그 득점왕 손흥민인데
[Minji] Sent message
[Sonny] Message arrived: 어 나 뉴진스 민진데
[Jenny] Message arrived: 어 나 뉴진스 민진데




목적

  1. 서로 상호작용하는 오브젝트들을 캡슐화함으로써 느슨한 결합을 유지
  2. 객체들 사이의 M : N 의 관계를 M : 1 관계로 바꿔 상호작용을 원활하게 함
  3. 객체 간의 많은 의존관계를 가지거나 상호작용이 복잡해질 때 사용

장점

  1. 효율적인 자원 관리 가능
  2. 객체간의 통신을 위해 서로 직접 참조할 필요가 없다
  3. 중재자 구현 클래스는 추후에 더 효율적인 클래스로 변경될 수 있다

단점

  1. 객체간의 통신 로직이 복잡해지거나 객체의 형태가 자주 변경되는 경우 유지보수 및 관리가 어렵다



참고


[디자인패턴] 디자인패턴이란? - 생성패턴, 구조패턴, 행위패턴

[Design Pattern] 중재자 패턴(Mediator Pattern)

[Design Pattern] 중재자 패턴 (Mediator Pattern)

profile
개발공부를해보자

0개의 댓글