반응형

의도

  • 여러 객체들이 소통하는 방법을 캡슐화하는 패턴
  • 한 집합에 속해있는 객체의 상호작용을 캡슐화하는 객체를 정의한다. 객체들이 직접 서로를 참조하지 않도록 하여 객체 사이의 느슨한 결합(loose coupling)을 촉진시키며, 개발자가 객체의 상호작용을 독립적으로 다양화시킬 수 있게 만든다.

 

장점

  • 여러 컴포넌트 간의 결합도를 중재자를 통해서 낮출 수 있다.
  • 컴포넌트의 코드를 변경하지 않고 새로운 중재자를 만들어 사용할 수 있다.
  • 각각의 컴포넌트 코드를 보다 간결하게 유지할 수 있다.

 

단점

  • 중재자 역할을 하는 클래스의 복잡도와 결합도가 증가한다.

 

알려진 사용 예

  • 자바
    • Executor
    • ExecutorService
  • 스프링
    • DispatcherServlet

 

활용성

  • 여러 객체가 잘 정의된 형태이기는 하지만 복잡한 상호작용을 가질 때
  • 객체간의 의존성이 구조화되지 않으며, 잘 이해하기 어려울 때
  • 한 객체가 다른 객체를 너무 많이 참조하고, 너무 많은 의사소통을 수행해서 그 객체를 재사용하기 힘들 때
  • 여러 클래스에 분산된 행동들이 상속 없이 상황에 맞게 수정되어야 할 때

 

결과

  • 서브클래싱을 제한한다.
    • 중재자는 다른 객체 사이에 분산된 객체의 행동들을 하나의 객체로 국한한다. 이 행동을 변경하고자 한다면 Mediator 클래스를 상속하는 서브클래스를 만들면 된다.
    • Colleague 클래스는 재사용 가능하다.
  • Colleague 객체 사이의 종속성을 줄인다.
    • 중재자는 행동에 참여하는 객체 간의 소결합을 촉진시킨다.
    • Mediator 클래스와 Colleague 클래스 각각을 독립적으로 다양화시킬 수 있고 재사용할 수 있다.
  • 객체 프로토콜을 단순화한다.
    • 중재자는 다 대 다의 관계를 일 대 다의 관계로 축소시킨다.
    • 일 대 다의 관계가 다 대 다 관계보다 이해하기 쉽고 유지보수 및 확장하기 쉽다.
  • 객체 간의 협력 방법을 추상화한다.
    • 객체 사이의 중재를 독립적인 개념으로 만들고 이를 캡슐화함으로써 사용자는 각 객체의 행동과 상관없이 객체 간 연결 방법에만 집중할 수 있다.
    • 결과적으로 시스템에서 객체가 어떻게 동작하는지 명확하게 알 수 있다.
  • 통제가 집중화된다.
    • 상호작용의 복잡한 모든 것들이 자신의 내부에서만 오가게 한다.
    • 중재자 객체는 동료 객체 간의 상호작용에 관련된 프로토콜을 모두 캡슐화하기 때문에 어느 동료 객체보다도 훨씬 복잡해질 수 있다. 따라서 Mediator 클래스 자체의 유지보수가 어려워지는 경우도 발생할 수 있다.

 

협력 방법

  • Colleague는 Mediator에서 요청을 송수신한다. Mediator는 필요한 Colleague 사이에 요청을 전달할 의무가 있다.

 

구조

  • 일반적인 객체 구조

 

실제 구현 구조

 

소스코드

//AbstractMediator
public interface FrontDesk {
    void getTowers(Guest guest, int numberOfTowers);

    String getRoomNumberFor();
}
//ConcreteMediator
public class DefaultFrontDesk implements FrontDesk{

    private final CleaningService cleaningService = new CleaningService(this);

    private Guest guest;

    public void getTowers(Guest guest, int numberOfTowers) {
        this.guest = guest;
        //컴포넌트 간의 결합도를 낮추기 위해서 중재자를 이용한다.
        //연관되어 있는 컴포넌트에 누구한테 응답을 줘야하는지 구체적으로 알려준다면 다시 컴포넌트 간의 결합이 생겨서 보내면 안된다.
        //따라서 요청을 처리하는데 필요한 만큼의 정보만 전달한다. 호텔 서비스를 제공하기 위해서는 회원의 아이디를 알면 된다.
        this.cleaningService.getTowers(guest.getId(), numberOfTowers); //회원의 방에 타월을 가져다준다.
    }

    public String getRoomNumberFor() {
        return guest.getRoomNumber();
    }
}
//Colleague
public class Guest {
    private Integer id;

    private String roomNumber;

    private final FrontDesk frontDesk;

    public Guest() {
        this.frontDesk = new DefaultFrontDesk();
    }

    public Guest(FrontDesk frontDesk) {
        this.frontDesk = frontDesk;
    }

    public void getTowers(int numberOfTowers) {
        this.frontDesk.getTowers(this, numberOfTowers);
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getRoomNumber() {
        return roomNumber;
    }

    public void setRoomNumber(String roomNumber) {
        this.roomNumber = roomNumber;
    }
}
//Colleague
public class CleaningService {

    //회원 아이디에 해당하는 방에 서비스를 제공할 수 있다.
    private final FrontDesk frontDesk;

    public CleaningService(FrontDesk frontDesk) {
        this.frontDesk = frontDesk;
    }

    public void getTowers(Integer guestId, int numberOfTowers) {
        String roomNumber = this.frontDesk.getRoomNumberFor();
        System.out.println("provide " + numberOfTowers + " towers to room " + roomNumber);
    }
}
public class Hotel {
    public static void main(String[] args) {
        Guest guest = new Guest();
        guest.setId(1);
        guest.setRoomNumber("100");
        guest.getTowers(3);

        Guest guest2 = new Guest();
        guest2.setId(5);
        guest2.setRoomNumber("2030");
        guest2.getTowers(5);
    }
}

 

관련 패턴

  • 퍼사드 패턴은 객체들로 구성된 서브시스템을 추상화하여 좀 더 편한 인터페이스를 제공하는 것이 목적이기 때문에 중재자 패턴과는 다르다.
    • Facade 객체는 서브시스템을 구성하는 객체로만 메시지가 전달되고 그 반대로 서브시스템을 구성하는 객체가 Facade 객체에 메시지 전달은 처리가 되지 않는다.
    • Mediator 객체는 Facade와 다르게 양방향으로 메시지 전달이 발생한다.
  • 상호 관련된 객체들은 감시자 패턴을 이용해서 중재자 객체들과 교류한다.

 


[참고자료]

리처드 헬름, 랄프 존슨, 존 블리시디스, 『GoF의 디자인 패턴 : 재사용성을 지닌 객체지향 소프트웨어의 핵심요소』, 김정아 번역, 프로텍미디어(2015)

http://www.cs.unc.edu/~stotts/GOF/hires/pat5efso.htm

코딩으로 학습하는 GoF의 디자인 패턴, 백기선

 

반응형

+ Recent posts