[ 디자인 패턴: 행동 ] (4) 중재자 (Mediator)

2025. 4. 12. 16:35·개발
반응형


 

중재자 : 객체 간의 직접 통신을 제한하고 중재자 객체를 통해서만 협력하게 함으로써,  객체 간의 혼란스러운 의존 관계를 줄이는 디자인 패턴

 


위와 같이 회원가입 및 로그인을 수행하는 팝업창이 있다고 해보자.

팝업창 내의 여러 요소들을 서로 상호작용 할 수 있다.

예를 들어, 로그인 버튼을 눌렀는데 실패했다면 "비밀번호가 올바르지 않습니다"와 같은 에러 메시지가 등장할 수 있다.

 

각각의 요소들은 다른 요소들과 많은 관계를 맺을 수 있다.

이에 따라, 일부 요소를 변경하면 다른 요소들에 영향을 줄 수 있다.

 

 

중재자 패턴은 이러한 상황에서 요소 간의 의존 관계를 줄여준다.

즉, 상호작용하는 각각의 객체를 캡슐화함으로써 느슨한 결합을 유지하는 것이다.

 


예제

 

사용자를 추가/제거 할 수 있고, 특정 사용자가 다른 모든 사용자에게 메시지를 보내는 시스템을 중재자 패턴을 적용하여 만들어보자!

 

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

 

위와 같이 중재자 인터페이스를 만든다.

 

public class UserMediator 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 sender, String message)
    {
        for(User receiver : userList)
        {
            if(sender != receiver)
                receiver.receive(message);
        }
    }
}

 

위와 같이 중재자 구현 클래스를 만든다.

 

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 send(String message);
    public abstract void receive(String message);
}

 

User 추상 클래스는 위와 같다.

사용자 객체들은 메시지를 주고 받기 위해 서로 통신할 수 있어야 한다.

 

public class ManUser extends User
{
    // 생성자
    public ManUser(Mediator mediator, String name) {
        super(mediator, name);
    }
    
    @Override
    public void send(String message)
    {
        System.out.println("[" + super.name + "] 상남자처럼 메시지 보내기");
        super.mediator.sendMessage(this, message);
    }

    @Override
    public void receive(String message)
    {
        System.out.println("[" + super.name + "] 상남자처럼 메시지 받기: " + message);
    }
}
public class WomanUser extends User
{
    // 생성자
    public WomanUser(Mediator mediator, String name) {
        super(mediator, name);
    }
    
    @Override
    public void send(String message)
    {
        System.out.println("[" + super.name + "] 상여자처럼 메시지 보내기");
        super.mediator.sendMessage(this, message);
    }

    @Override
    public void receive(String message)
    {
        System.out.println("[" + super.name + "] 상여자처럼 메시지 받기: " + message);
    }
}

 

사용자 추상 클래스를 상속받는 클래스들은 위와 같다.

성별에 따라 클래스를 분리하였다.

 

사용자 객체들은 중재자를 통해 서로 메시지를 주고받을 수 있다.

 

public class Client
{
    public static void main(String[] args)
    {
        Mediator mediator = new UserMediator();

        User user1 = new ManUser(mediator, "민수");
        User user2 = new ManUser(mediator, "재훈");
        User user3 = new WomanUser(mediator, "민지");
        User user4 = new WomanUser(mediator, "영희");
        
        mediator.addUser(user1);
        mediator.addUser(user2);
        mediator.addUser(user3);
        mediator.addUser(user4);
        
        mediator.removeUser(user4);

        user1.send("민수의 메시지 보내기 권법");
        user3.send("영희의 메시지 폭격 블래스터");
    }
}

 

위와 같이 중재자가 사용자 객체를 관리하고, 서로 통신할 수 있게 해준다.

 

각각의 사용자 객체에서 다른 사용자 객체를 참조하고 있지 않지만, 메시지를 보낼 수 있다!

서로를 참조하는 대신, 공통의 중재자를 참조하는 것이다.

 


사용 시기

 

  • 일부 클래스가 다른 클래스와 단단하게 결합하여 변경하기 어려울 때
  • 어떤 컴포넌트가 다른 컴포넌트에 너무 의존해서 재사용할 수 없을 때
  • 서로 상호작용하는 객체들을 캡슐화함으로써 느슨한 결합을 유지해야 할 때
  • 객체 들 사이의 M : N 관계를 M : 1 관계로 바꿔서 상호작용을 원할하게 해야 할 때
  • 객체 간의 의존 관계가 너무 많을 때

 


장점

 

  • 객체가 서로 통신하기 위해, 서로를 참조하지 않아도 된다.
  • 컴포넌트 간의 결합도를 줄일 수 있다.
  • 컴포넌트의 재사용성이 올라간다.
  • SRP 만족 : 다양한 컴포넌트 간의 통신을 한 곳에서 관리할 수 있다.
  • OCP 만족 : 컴포넌트를 변경하지 않고 새로운 중재자를 도입할 수 있다.

 


단점

 

  • 객체 간의 통신 로직이 복잡해진다.
  • 객체의 형태가 자주 변경되는 경우에는 적합하지 않다.
  • 중재자의 권한이 너무 커진다.

 


 

 

참고:

https://inpa.tistory.com/entry/GOF-%F0%9F%92%A0-%EB%B0%98%EB%B3%B5%EC%9E%90Iterator-%ED%8C%A8%ED%84%B4-%EC%99%84%EB%B2%BD-%EB%A7%88%EC%8A%A4%ED%84%B0%ED%95%98%EA%B8%B0#%ED%8C%A8%ED%84%B4_%EC%82%AC%EC%9A%A9_%EC%8B%9C%EA%B8%B0

https://velog.io/@dnjsdn96/%EB%94%94%EC%9E%90%EC%9D%B8%ED%8C%A8%ED%84%B4-%EC%A4%91%EC%9E%AC%EC%9E%90-%ED%8C%A8%ED%84%B4-Mediator-Pattern

 

 

반응형
저작자표시 비영리 변경금지 (새창열림)

'개발' 카테고리의 다른 글

[ 디자인 패턴: 행동 ] (6) 옵저버 (Observer)  (0) 2025.04.12
[ 디자인 패턴: 행동 ] (5) 메멘토 (Memento, Snapshot)  (0) 2025.04.12
[ 디자인 패턴: 행동 ] (3) 반복자 (Iterator)  (0) 2025.04.12
[ 디자인 패턴: 행동 ] (2) 커맨드, 명령 (Command)  (0) 2025.04.12
[ 디자인 패턴: 행동 ] (1) 책임 연쇄 (Chain of Responsibility, CoR)  (0) 2025.04.12
'개발' 카테고리의 다른 글
  • [ 디자인 패턴: 행동 ] (6) 옵저버 (Observer)
  • [ 디자인 패턴: 행동 ] (5) 메멘토 (Memento, Snapshot)
  • [ 디자인 패턴: 행동 ] (3) 반복자 (Iterator)
  • [ 디자인 패턴: 행동 ] (2) 커맨드, 명령 (Command)
sleepzzz214
sleepzzz214
응애 개발자 공부 블로그입니다!
  • sleepzzz214
    응애 개발자의 일지
    sleepzzz214
  • 전체
    오늘
    어제
    • ⭐ (64)
      • 개발 (64)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    생성 패턴
    상태 패턴
    싱글톤
    모니터링
    구조 패턴
    JVM
    docker
    스프링
    javac
    DB
    데이터베이스
    객체 지향 설계
    행동 패턴
    Spring boot
    대규모 트래픽
    스프링부트
    디자인 패턴
    객체 지향 프로그래밍
    의존성 주입
    제어의 역전
    도커
    스프링 핵심 원리 - 기본편
    스프링 빈
    김영한 스프링 강의
    싱글톤 패턴
    Kafka
    Spring
    자바
    의존 관계 주입
    java
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
sleepzzz214
[ 디자인 패턴: 행동 ] (4) 중재자 (Mediator)
상단으로

티스토리툴바