티스토리 뷰
정의
- 수많은 객체들이 서로 복잡하게 상호작용 하는 경우, 하나의 중재자 클래스를 통해서만 간접적으로 communication 하게 만드는 pattern.
- 객체들의 M:N 관계를 Mediator를 통해 1:N 관계로 만들어 줌.
- concreateCollegue1, concreateCollegue2, 3, 4 등의 수많은 객체가 서로 참조하며 복잡하게 상호작용 하는 상황일 경우, 위 diagram 처럼 Mediator 클래스를 통해 각 객체가 간접적으로 comunication 할 수 있다.
- 이는 객체들간의 coupling(결합도)를 줄임으로써 재사용성을 높일 수 있고, 객체간의 유지보수에 용이하다.
예제
book, view, search 3개의 Button과 상태를 표시하는 Label 로 구성되는 Java AWT gui를 만들어 보자.
요구사항은 아래와 같다.
- book button을 누르면 book button이 비활성화 되고, 나머지 button이 활성화 됨. Label에는 "booking..." 이라고 표시
- view button을 누르면 view button이 비활성화 되고, 나머지 button이 활성화 됨. Label에는 "Viewing..." 이라고 표시
- 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 하는 구조.
'Programing > DesignPattern' 카테고리의 다른 글
Composite 패턴 (0) | 2016.08.24 |
---|---|
Singleton 패턴 (0) | 2016.08.24 |
Decorator 패턴 (0) | 2016.08.17 |
[디자인패턴] 2. Adapter 패턴 - 바꿔서 재이용하기 (0) | 2013.02.05 |
[디자인 패턴] 1. Iterator 패턴 - 순서대로 지정해서 처리하기 (0) | 2013.02.04 |
댓글