티스토리 뷰

Programing/DesignPattern

Mediator 패턴

오통 2016. 8. 22. 20:50

정의


  • 수많은 객체들이 서로 복잡하게 상호작용 하는 경우, 하나의 중재자 클래스를 통해서만 간접적으로 communication 하게 만드는 pattern.
  • 객체들의 M:N 관계를 Mediator를 통해 1:N 관계로 만들어 줌.

 

  • concreateCollegue1, concreateCollegue2, 3, 4 등의 수많은 객체가 서로 참조하며 복잡하게 상호작용 하는 상황일 경우, 위 diagram 처럼 Mediator 클래스를 통해 각 객체가 간접적으로 comunication 할 수 있다.
  • 이는 객체들간의 coupling(결합도)를 줄임으로써 재사용성을 높일 수 있고, 객체간의 유지보수에 용이하다.


예제


book, view, search 3개의 Button과 상태를 표시하는 Label 로 구성되는 Java AWT gui를 만들어 보자.

요구사항은 아래와 같다.


  1.  book button을 누르면 book button이 비활성화 되고, 나머지 button이 활성화 됨. Label에는 "booking..." 이라고 표시
  2. view button을 누르면 view button이 비활성화 되고, 나머지 button이 활성화 됨. Label에는 "Viewing..." 이라고 표시
  3. search button을 누르면 search button이 비활성화 되고, 나머지 button이 활성화 됨. Label에는 "searching..." 이라고 표시



// Collegue interface
interface Collegue {
    void execute();
}

// Mediator interface
interface Mediator {
     // 중재자는 모든 Collegue를 알고 있어야 함. Collegue들의 상호작용을 대신하기 위해.
    void registerView(BtnView v);
    void registerSearch(BtnSearch s);
    void registerBook(BtnBook b);
    void registerDisplay(LblDisplay d);
    // 각각의 Collegue들이 다른 객체와 상호작용 하기 위해 호출 할 book(), view(), search() method
    void book();
    void view();
    void search();   
}

class ConcreateMediator implements Mediator {
    BtnView btnView;
    BtnSearch btnSearch;
    BtnBook btnBook;
    LblDisplay show;
    public void registerView(BtnView v) {
        btnView = v;
    }

    public void registerSearch(BtnSearch s) {
        btnSearch = s;
    }

    public void registerBook(BtnBook b) {
        btnBook = b;
    }

    public void registerDisplay(LblDisplay d) {
        show = d;
    }
    
    // 핵심이 되는 부분! ConcreateMediator 클래스에서 각각의 Collegue 들의 상태로 변경 하고 있음.
    public void book() {
        btnBook.setEnabled(false);
        btnView.setEnabled(true);
        btnSearch.setEnabled(true);
        show.setText("booking...");
    }

    public void view() {
        btnView.setEnabled(false);
        btnSearch.setEnabled(true);
        btnBook.setEnabled(true);
        show.setText("viewing...");
    }

    public void search() {
        btnSearch.setEnabled(false);
        btnView.setEnabled(true);
        btnBook.setEnabled(true);
        show.setText("searching...");
    }
 }

//A concrete colleague
class BtnView extends JButton implements Command {

    Mediator med;

    BtnView(ActionListener al, Mediator m) {
        super("View");
        addActionListener(al);
        med = m;
        med.registerView(this);
    }

    public void execute() {
        med.view();
    }
 }
//A concrete colleague
class BtnSearch extends JButton implements Command {

    Mediator med;

    BtnSearch(ActionListener al, Mediator m) {
        super("Search");
        addActionListener(al);
        med = m;
        med.registerSearch(this);
    }

    public void execute() {
        med.search();
    }
    
}

//A concrete colleague
class BtnBook extends JButton implements Command {

    Mediator med;

    BtnBook(ActionListener al, Mediator m) {
        super("Book");
        addActionListener(al);
        med = m;
        med.registerBook(this);
    }

    public void execute() {
        med.book();
    }

}

class LblDisplay extends JLabel {

    Mediator med;

    LblDisplay(Mediator m) {
        super("Just start...");
        med = m;
        med.registerDisplay(this);
        setFont(new Font("Arial", Font.BOLD, 24));
    }

}

class MediatorDemo extends JFrame implements ActionListener {

    Mediator med = new ParticipantMediator();

    MediatorDemo() {
        // Panel을 만들고 각각의 button을 add한다.
        JPanel p = new JPanel();
        p.add(new BtnView(this, med));
        p.add(new BtnBook(this, med));
        p.add(new BtnSearch(this, med));
        getContentPane().add(new LblDisplay(med), "North");
        getContentPane().add(p, "South");
        setSize(400, 200);
        setVisible(true);
    }

    // 각각의 Button에 ActionListener를 add 했으므로, 각 button이 click 될 때 호출 됨.
    public void actionPerformed(ActionEvent ae) {
        Command comd = (Command) ae.getSource();
        comd.execute();
    }

    public static void main(String[] args) {
        new MediatorDemo();
    }
}

결론


Collegue 객체들이 서로서로를 참조 하고 있으면 클래스간의 Coupling으로 재사용에 용이 하지 않다. Mediator 중개자 class를 통해 각 Collegue들이 간접적으로 서로 communication함으로써 Coupling을 없애고 재사용 가능한 구조가 된다.


장점

  • 클래스간의 Coupling이 줄어들어 코드 재사용에 좋음.

단점
  • Collegue 객체들의 수가 많고 서로 상호작용하는 case가 복잡할 수록 Mediator도 복잡해지고 거대해짐.
참고
Facade 패턴과의 차이
- Facade는 대표가 되는 창구 class를 통해 단방향 communication 하지만 Mediator는 Mediator와 Collegue간 양방향 comunication 하는 구조.




댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
TAG
more
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함