중재자(Mediator) 패턴

중재자 패턴은 복잡한 객체 간의 상호 작용을 단순화하기 위해 중재자 객체를 도입하는 디자인 패턴입니다. 중재자 객체는 다른 객체 간의 통신을 캡슐화하고 객체 간의 의존성을 줄이는 데 도움이 됩니다.

구성 요소

구현:

  1. 인터페이스 생성: 중재자 역할을 수행할 인터페이스를 정의합니다.
  2. 중재자 구현: 인터페이스를 구현하는 중재자 클래스를 생성합니다. 중재자는 여러 개의 동료 객체들과 통신하며, 필요한 작업을 수행합니다.
  3. 동료 객체 구현: 중재자와 연결할 여러 개의 동료 객체를 생성합니다.
  4. 동료 객체와 중재자 연결: 동료 객체들은 중재자의 인스턴스를 참조하여 연결합니다.

장점

단점

예시

손님은 레스토랑에 예약을 하거나, 청소업체에 룸 청소를 부탁하거나, 타월을 요청할때 프론트데스크만 알고 있으면된다.

Mediator

public class FrontDesk {

    private final CleaningService cleaningService;
    private final Gym gym;
    private final Restaurant restaurant;

    public FrontDesk(CleaningService cleaningService, Gym gym, Restaurant restaurant) {
        this.cleaningService = cleaningService;
        this.gym = gym;
        this.restaurant = restaurant;
    }

    public void getTower(int roomNumber, int numberOfTower) {
        this.cleaningService.getTower(roomNumber, numberOfTower);
    }

    public void cleanGym() {
        this.cleaningService.clean(this.gym);
    }

    public void cleanRestaurant(){
        this.cleaningService.clean(this.restaurant);
    }

    public void dinner(int roomNumber, LocalDateTime time) {
        this.restaurant.dinner(roomNumber, time);
    }

    public int getRoomNumber(){
        return 1111;
    }
}

Colleague

public class CleaningService {
    public void clean(Gym gym) {
        System.out.println("clean " + gym);
    }

    public void getTower(int roomNumber, int numberOfTower) {
        System.out.println(numberOfTower + " towers to " + roomNumber);
    }

    public void clean(Restaurant restaurant) {
        System.out.println("clean " + restaurant);
    }
}

public class Restaurant {

    public void dinner(int roomNumber, LocalDateTime time) {
        System.out.println("dinner " + roomNumber + " at " + time.format(DateTimeFormatter.ofPattern("yyyy-MM-dd hh:mm")));
    }
}

public class Gym {

    private FrontDesk frontDesk;
}

Client

public class Guest {

    private int roomNumber;

    private final FrontDesk frontDesk;

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

    public void dinner(LocalDateTime time) {
        frontDesk.dinner(this.roomNumber, time);
    }

    public void getTower(int numberOfTower) {
        frontDesk.getTower(this.roomNumber, numberOfTower);
    }

    public void setRoomNumber(int roomNumber) {
        this.roomNumber = roomNumber;
    }
}

class HotelTest {

    @Test
    public void guest_test() {
        FrontDesk frontDesk = new FrontDesk(new CleaningService(), new Gym(), new Restaurant());

        Guest guest = new Guest(frontDesk);
        guest.setRoomNumber(frontDesk.getRoomNumber());
        guest.getTower(3);
        guest.dinner(LocalDateTime.now());

        frontDesk.cleanGym();
        frontDesk.cleanRestaurant();
    }

}

결론

중재자 패턴은 복잡한 시스템에서 객체간 상호작용을 조율하는 유용한 디자인 패턴입니다. 이 패턴을 사용하면 객체간 결합도를 줄이고 유연성과 확장성을 향상시킬 수 있습니다. 단, 너무 많은 역할을 부여하면 중재자에게 의존성이 과도하게 집중되어 오버헤드가 발생해 성능문제가 생길 수 있다.

예제는 이곳 에서 확인하실수 있습니다.