개발/디자인패턴

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

nova_dev 2022. 3. 24. 00:00
반응형

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

중재자 패턴은 분산된 다수의 객체 역할을 조정할 때 주로 사용한다.

 

 중재자 패턴이란?

  • 중재자 패턴은 객체의 관계를 하나의 객체로 정리하는 패턴이다.
  • 중자재 패턴은 서로 의존적인 M:N 관계를 가진 객체를 느슨한 1:1 관계로 변경한다
  • 복잡한 통신과 제어를 한 곳에 집중하여 처리하는 효과가 있다.
  • 다른 동료 객체에 직접 접근해서 호출하지 않고 중재자를 의존해서 다른 동료 객체를 호출한다.
  • 중재자 패턴은 객체의 강력한 구조적 결합 문제점을 해결한다.
  • 중재자를 이용하지 않으면 다수의 동료 객체가 서로 정보를 직접 주고받는다. 중재자 패턴은 동료 객체끼리 정보를 직접 주고받지 않도록 통신 경로를 제한한다.
  • 중재자는 하나의 객체 요청에 대해 모든 객체로 통보를 처리해야 하므로 경로의 수가 증가한다.
  • 중재자 패턴을 설계할 때는 경로의 수가 증가함에 따라 성능이 저하되지 않도록 신경써서 구성해야 한다.

 

 중재자 패턴 구조

  • Mediator
    • 동료 간 통신을 위한 인터페이스
  • Collegue
    • 동료 간에 전달되는 이벤트를 정의하는 추상 클래스
  • ConcreteMedediator
    • Colleague 객체를 조정하여 협동 조작을 구현하고 동료를 유지 관리
  • ConcreteColleague
    • 다른 Colleague가 생성한 Mediator를 통해 받은 알림 작업을 구현

 중재자 패턴 코드

1. Mediator 인터페이스

public interface Mediator {

    void addColleague(Colleague colleague);

    void mediate(Colleague colleague);
}

2. ColleagueType enum

public enum ColleagueType {
    USER, SYSTEM, ADMIN
}

3. Colleague 추상 클래스

public abstract class Colleague {
    private Mediator mediator;
    private String message;
    private final String name;
    private final ColleagueType type;

    protected Colleague(String name, ColleagueType type) {
        this.name = name;
        this.type = type;
    }

    public void setMediator(Mediator mediator) {
        this.mediator = mediator;
    }

    public void setMessage(String message) {
        this.message = message;
    }

    public Mediator getMediator() {
        return mediator;
    }

    public String getMessage() {
        return message;
    }

    public String getName() {
        return name;
    }

    public ColleagueType getType() {
        return type;
    }

    public void send() {
        System.out.println(this.name + " send()");
        System.out.println();
        mediator.mediate(this);
    }

    public abstract void receive(Colleague colleague);

}

4. Colleague 구체 클래스

public class UserConcreteColleague extends Colleague {
    public UserConcreteColleague(String name) {
        super(name, ColleagueType.USER);
    }

    @Override
    public void receive(Colleague colleague) {
        if (ColleagueType.SYSTEM == colleague.getType()) {
            System.out.print("[SYSTEM] ");
        } else if (ColleagueType.USER == colleague.getType()) {
            System.out.print("[" + colleague.getName() + "] ");
        }
        System.out.println(colleague.getMessage());
    }
}
public class SystemConcreteColleague extends Colleague {
    public SystemConcreteColleague(String name) {
        super(name, ColleagueType.SYSTEM);
    }

    @Override
    public void receive(Colleague colleague) {
        System.out.println("System can't receive messages");
    }
}
public class AdminConcreteColleague extends Colleague {
    public AdminConcreteColleague(String name) {
        super(name, ColleagueType.ADMIN);
    }

    @Override
    public void receive(Colleague colleague) {
        System.out.println("Admin can't receive messages");
    }
}

5. Mediator 테스트 코드

class MediatorTest {
    @Test
    @DisplayName("Mediator 테스트")
    void mediatorTest() {
        Mediator mediator = new ConcreteMediator();
        Colleague colleagueUser1 = new UserConcreteColleague("User1");
        Colleague colleagueUser2 = new UserConcreteColleague("User2");
        Colleague colleagueSystem = new SystemConcreteColleague("System");
        Colleague colleagueAdmin = new AdminConcreteColleague("Admin");

        colleagueUser1.setMediator(mediator);
        colleagueUser2.setMediator(mediator);
        colleagueSystem.setMediator(mediator);
        colleagueAdmin.setMediator(mediator);

        mediator.addColleague(colleagueUser1);
        mediator.addColleague(colleagueUser2);
        mediator.addColleague(colleagueSystem);
        mediator.addColleague(colleagueAdmin);

        colleagueUser1.setMessage("안녕하세요. User1이 보낸 메시지 입니다.");
        colleagueUser1.send();

        colleagueUser2.setMessage("안녕하세요. User2가 보낸 메시지 입니다.");
        colleagueUser2.send();

        colleagueSystem.setMessage("잠시 후 20분 뒤에 점검이 있습니다.");
        colleagueSystem.send();
    }

}

 

 중재자 패턴의 특징

양방향

  • 중재자 패턴은 다른 패턴들과 달리 양방향 통신을 처리한다.
    1. concreteColleague에서 중재자로 데이터 전송
    2. 메시지를 전달 받은 동료 갹체는 수신한 메시지를 다시 중개 객체로 전송
    3. 전송 받은 중개 객체는 동작을 분석한 후 처리 의무가 있는 다른 동료 객체에게 행위를 요청
    4. 중재자 패턴은 Mediator와 Colleague 사이를 양방향 통신하면서 요청한 행위를 조정

 

 

 Github 코드

Github 예제 코드 링크

Github 예제 테스트 코드 링크

참고 자료

 

 

 

 

 

반응형