출처 : 책 - java 언어로 배우는 디자인 패턴 입문
16. Mediator - 중개인을 통해서 처리하기
1. 목적
- A 클래스, B클래스, C클래스 가 서로 얽혀 있는 경우 클래스의 상관 관계가 복잡해진다.
- M(Mediator) 클래스를 만들어서 A,B,C 클래스의 정보를 M 클래스로 모은 다음 M클래스가 A, B, C를 제어한다.
구체적인 방법으로, M클래스 안에 A, B, C 클래스의 인스턴스를 만들고, A, B, C가 변할때마다 M 클래스의
특정 로직 메소드를 호출한다. 이 메소드가 A, B, C의 상태를 재정의한다.
- 새로운 D 클래스가 추가 되었을 때 중재자 M 클래스는 재사용하기 어렵다.
로직이 몰려 있는 M 클래스에 D로직이 추가되기 때문이다.
하지만 로직이 M 클래스에 있는 덕분에 기존 A, B, C 는 그대로 사용할 수 있다.
2.예제
●Guest ○User
ID :
PW :
확인 취소
의 로그인 창을 만드는 예제이다.
(1) Mediator 인터페이스 - 중재자 인터페이스
createColleagues : 동료 클래스들을 생성
colleagueChanged : 동료클래스들의 상태를 재정의한다.
public interface Mediator {
public abstract void createColleagues();
public abstract void colleagueChanged();
}
(2) Colleague 인터페이스 - 중재해줄 클래스(동료)들의 인터페이스
- setMediator : 중재자가 누구인지 설정
- setColleagueEnabled : 나(Colleague)의 상태를 세팅
public interface Colleague {
public abstract void setMediator(Mediator mediator);
public abstract void setColleagueEnabled(boolean enabled);
}
(3) ColleagueButton - 동료1
import java.awt.Button;
public class ColleagueButton extends Button implements Colleague {
private Mediator mediator;
public ColleagueButton(String caption) {
super(caption);
}
public void setMediator(Mediator mediator) { // Mediator을 저장
this.mediator = mediator;
}
public void setColleagueEnabled(boolean enabled) { // Mediator에서 유효/무효를 지시
setEnabled(enabled);
}
}
(4) ColleagueTextField - 동료2
import java.awt.TextField;
import java.awt.Color;
import java.awt.event.TextListener;
import java.awt.event.TextEvent;
public class ColleagueTextField extends TextField implements TextListener, Colleague {
private Mediator mediator;
public ColleagueTextField(String text, int columns) { // 생성자
super(text, columns);
}
public void setMediator(Mediator mediator) { // Mediator을 저장
this.mediator = mediator;
}
public void setColleagueEnabled(boolean enabled) { // Mediator에서 유효/무효를 지시
setEnabled(enabled);
setBackground(enabled ? Color.white : Color.lightGray);
}
public void textValueChanged(TextEvent e) { // 문자열이 변하면 Mediator에게 통지
mediator.colleagueChanged();
}
}
(5) ColleagueCheckbox - 동료3
import java.awt.Checkbox;
import java.awt.CheckboxGroup;
import java.awt.event.ItemListener;
import java.awt.event.ItemEvent;
public class ColleagueCheckbox extends Checkbox implements ItemListener, Colleague {
private Mediator mediator;
public ColleagueCheckbox(String caption, CheckboxGroup group, boolean state) {
// 생성자
super(caption, group, state);
}
public void setMediator(Mediator mediator) { // Mediator을 저장
this.mediator = mediator;
}
public void setColleagueEnabled(boolean enabled) { // Mediator에서 유효/무효를 지시
setEnabled(enabled);
}
public void itemStateChanged(ItemEvent e) { // 상태가 바뀌면 Mediator에게 통지
mediator.colleagueChanged();
}
}
(6) LoginFrame - Mediator 인터페이스, 중재자 역할
- 동료들을 제어하는 메소드들
colleagueChanged : Guest 버튼을 클릭시, ID, PW 입력 불가.
userpassChanged : ID가 빈칸이면 PW 입력 및 OK 버튼 비활성화.
ID가 입력됐을때 PW가 빈칸이면 OK 버튼 비활성화.
ID, PW 모두 입력시 OK 버튼 활성화
import java.awt.Frame;
import java.awt.Label;
import java.awt.Color;
import java.awt.CheckboxGroup;
import java.awt.GridLayout;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
public class LoginFrame extends Frame implements ActionListener, Mediator {
private ColleagueCheckbox checkGuest;
private ColleagueCheckbox checkLogin;
private ColleagueTextField textUser;
private ColleagueTextField textPass;
private ColleagueButton buttonOk;
private ColleagueButton buttonCancel;
// 생성자
// Colleague들을 생성하고, 배치한 후에 표시를 실행한다
public LoginFrame(String title) {
super(title);
setBackground(Color.lightGray);
// 레이아웃 매니저를 사용해서 4X2의 그리드를 만든다
setLayout(new GridLayout(4, 2));
// Colleague들의 생성
createColleagues();
// 배치
add(checkGuest);
add(checkLogin);
add(new Label("Username:"));
add(textUser);
add(new Label("Password:"));
add(textPass);
add(buttonOk);
add(buttonCancel);
// 유효/무효의 초기 지정
colleagueChanged();
// 표시
pack();
show();
}
// Colleague들을 생성한다
public void createColleagues() {
// 생성
CheckboxGroup g = new CheckboxGroup();
checkGuest = new ColleagueCheckbox("Guest", g, true);
checkLogin = new ColleagueCheckbox("Login", g, false);
textUser = new ColleagueTextField("", 10);
textPass = new ColleagueTextField("", 10);
textPass.setEchoChar('*');
buttonOk = new ColleagueButton("OK");
buttonCancel = new ColleagueButton("Cancel");
// Mediator의 세트
checkGuest.setMediator(this);
checkLogin.setMediator(this);
textUser. setMediator(this);
textPass. setMediator(this);
buttonOk. setMediator(this);
buttonCancel.setMediator(this);
// Listener의 세트
checkGuest.addItemListener(checkGuest);
checkLogin.addItemListener(checkLogin);
textUser.addTextListener(textUser);
textPass.addTextListener(textPass);
buttonOk.addActionListener(this);
buttonCancel.addActionListener(this);
}
// Colleage에서의 통지로 Colleage의 유효/무효를 판정한다
public void colleagueChanged() {
if (checkGuest.getState()) { // Guest 모드
textUser.setColleagueEnabled(false);
textPass.setColleagueEnabled(false);
buttonOk.setColleagueEnabled(true);
} else { // Login 모드
textUser.setColleagueEnabled(true);
userpassChanged();
}
}
// textUser 또는 textPass의 변경이 있었다
// 각 Colleage의 유효/무효를 판정한다
private void userpassChanged() {
if (textUser.getText().length() > 0) {
textPass.setColleagueEnabled(true);
if (textPass.getText().length() > 0) {
buttonOk.setColleagueEnabled(true);
} else {
buttonOk.setColleagueEnabled(false);
}
} else {
textPass.setColleagueEnabled(false);
buttonOk.setColleagueEnabled(false);
}
}
public void actionPerformed(ActionEvent e) {
System.out.println(e.toString());
System.exit(0);
}
}
(7) Main
import java.awt.*;
import java.awt.event.*;
public class Main {
static public void main(String args[]) {
new LoginFrame("Mediator Sample");
}
}
'개발 > 디자인 패턴' 카테고리의 다른 글
[Java 언어로 배우는 디자인 패턴 입문] 상태를 관리하기 18. Memento (0) | 2021.01.15 |
---|---|
[Java 언어로 배우는 디자인 패턴 입문] 상태를 관리하기 17. Observer (0) | 2021.01.14 |
[Java 언어로 배우는 디자인 패턴 입문] 단순화하기 15. Facade (0) | 2021.01.12 |
[Java 언어로 배우는 디자인 패턴 입문] 구조를 돌아다니기 14. Chain of Responsibility (0) | 2021.01.12 |
[Java 언어로 배우는 디자인 패턴 입문] 구조를 돌아다니기 13. Visitor (0) | 2021.01.11 |
댓글