Mediator 패턴
아래 결과화면부터 보시는 것도 이해하는데 좋습니다.
이름 |
해설 |
Mediator |
‘중개인’의 인터페이스를 결정하는 인터페이스 |
Colleague |
‘회원’의 인터페이스를 결정하는 인터페이스 |
ColleagueButton |
Colleague 인터페이스를 구현 버튼을 나타냄 |
ColleagueTextField |
Colleague 인터페이스를 구현 텍스트입력을 나타냄 |
ColleagueCheckbox |
Colleague인터페이스를 구현 체크박스(라디오버튼)을 나타냄 |
LoginFrame |
Mediator 인터페이스를 구현, 로그인 다이얼로그를 나타내는 클래스 |
Main |
동작 테스트용의 클래스 |
Mediator 인터페이스
package kch;
public interface Mediator {//중개인
public abstract void createColleagues();//회원을 생성하는 메소드
public abstract void colleagueChanged();//각 회원들에게서 호출되는 메소드
//상담을 의미함
}
Colleague 인터페이스
package kch;
public interface Colleague {
public abstract void setMediator(Mediator mediator);
public abstract void setColleagueEnabled(boolean enabled);
}
ColleagueButton
package kch;
import java.awt.Button;
public class ColleagueButton extends Button implements Colleague{
/**
* @uml.property name="mediator"
* @uml.associationEnd
*/
private Mediator mediator;
public ColleagueButton(String caption){
super(caption);
}
/**
* @param mediator
* @uml.property name="mediator"
*/
@Override
public void setMediator(Mediator mediator) {//mediator를 저장
// TODO Auto-generated method stub
this.mediator = mediator;
}
//Mediator 에게 알려줌,
@Override
public void setColleagueEnabled(boolean enabled) {
// TODO Auto-generated method stub
//Mediator에서 유효/무효를 지시
setEnabled(enabled);//Button 클래스 메소드
}
}
ColleagueTextField
package kch;
import java.awt.Color;
import java.awt.TextField;
import java.awt.event.TextEvent;
import java.awt.event.TextListener;
public class ColleagueTextField extends TextField implements TextListener, Colleague{
/**
* @uml.property name="mediator"
* @uml.associationEnd
*/
private Mediator mediator;
public ColleagueTextField(String text, int columns){
super(text, columns);
}
/**
* @param mediator
* @uml.property name="mediator"
*/
@Override
public void setMediator(Mediator mediator) {
// TODO Auto-generated method stub
this.mediator = mediator;
}
@Override
public void setColleagueEnabled(boolean enabled) {
// TODO Auto-generated method stub
setEnabled(enabled);
setBackground(enabled ? Color.white : Color.lightGray);
}
//Mediator 에게 알려줌,
@Override
public void textValueChanged(TextEvent e) {
// TODO Auto-generated method stub
mediator.colleagueChanged();//LoginFrame에 colleagueChanged()메소드가 구현됨.
}
}
ColleaugeCheckbox 클래스
package kch;
import java.awt.Checkbox;
import java.awt.CheckboxGroup;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
public class ColleagueCheckbox extends Checkbox implements ItemListener, Colleague{
/**
* @uml.property name="mediator"
* @uml.associationEnd
*/
private Mediator mediator;
public ColleagueCheckbox(String caption, CheckboxGroup group, boolean state){
super(caption, group, state);//생성자
}
/**
* @param mediator
* @uml.property name="mediator"
*/
@Override
public void setMediator(Mediator mediator) {
// TODO Auto-generated method stub
this.mediator = mediator;//Mediator를 저장
}
@Override
public void setColleagueEnabled(boolean enabled) {
// TODO Auto-generated method stub
setEnabled(enabled);//Mediator에서 유효/무효를 지시
}
//다음은 리스너임. 리스너란 값이 변하게 되면 자동적으로 여기로 옴.
//Mediator 에게 알려줌,
@Override
public void itemStateChanged(ItemEvent arg0) {
// TODO Auto-generated method stub
mediator.colleagueChanged();//상태가 바뀌면 Mediator에게 통지
//LoginFrame에 colleagueChanged()메소드가 구현됨.
}
}
LoginFrame 클래스
package kch;
import java.awt.CheckboxGroup;
import java.awt.Color;
import java.awt.Frame;
import java.awt.GridLayout;
import java.awt.Label;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class LoginFrame extends Frame implements ActionListener, Mediator{
/**
* @uml.property name="checkGuest"
* @uml.associationEnd multiplicity="(1 1)"
*/
private ColleagueCheckbox checkGuest;//라디오버튼 생성
/**
* @uml.property name="checkLogin"
* @uml.associationEnd multiplicity="(1 1)"
*/
private ColleagueCheckbox checkLogin;//라디오버튼 생성
/**
* @uml.property name="textUser"
* @uml.associationEnd multiplicity="(1 1)"
*/
private ColleagueTextField textUser;//텍스트필드 생성
/**
* @uml.property name="textPass"
* @uml.associationEnd multiplicity="(1 1)"
*/
private ColleagueTextField textPass;//텍스트필드 생성
/**
* @uml.property name="buttonOk"
* @uml.associationEnd multiplicity="(1 1)"
*/
private ColleagueButton buttonOk;//버튼 생성
/**
* @uml.property name="buttonCancel"
* @uml.associationEnd multiplicity="(1 1)"
*/
private ColleagueButton buttonCancel;//버튼 생성
//생성자
//Colleague들을 생성하고, 배치한 후에 표시를 실행한다.
@SuppressWarnings("deprecation")
public LoginFrame(String title){
super(title);
setBackground(Color.lightGray);//로그인 프레임 바탕색 설정
//레이아웃 매니저를 사용해서 4*2의 그리드를 만든다.
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();
}
@Override
public void createColleagues() {
// TODO Auto-generated method stub
CheckboxGroup g = new CheckboxGroup();
checkGuest = new ColleagueCheckbox("Guest", g, true);//라디오버튼을 그룹으로 묶음
checkLogin = new ColleagueCheckbox("Login", g, false);//둘중에 하나만 선택가능하게됨.
textUser = new ColleagueTextField("", 10);//길이는는 10
textPass = new ColleagueTextField("", 10);
textPass.setEchoChar('*');//비밀번호이므로 *로 입력되게 함.
buttonOk = new ColleagueButton("OK");//버튼이름이 OK
buttonCancel = new ColleagueButton("Cancel");//버튼이름이 Cancel
//Mediator의 세트
checkGuest.setMediator(this);//this 는 Mediator를 구현한 LoginFrame을 의미함.
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);//왜 this로 넘겼는지 이해안됨. 리스너를 구현안해서 그런가?
//원래 버튼같은것은 clickListener가 있음
buttonCancel.addActionListener(this);
}
//--------------여기가 핵심------------------------
//Colleague에서의 통지로 Colleague의 유효 무효를 판정한다.
//회원들로부터 일이 발생하면?
//중재인이 어떤일인지 파악하고 누가 해야될일인지 처리함.
@Override
public void colleagueChanged() {
// TODO Auto-generated method stub
if(checkGuest.getState()){//라디오버튼 상태 추적 게스트일경우는
textUser.setColleagueEnabled(false);//ID입력 비활성
textPass.setColleagueEnabled(false);//PASS입력 비활성
buttonOk.setColleagueEnabled(true);//OK버튼 비활성
}else{//게스트가 아닐 경우.
textUser.setColleagueEnabled(true);//ID입력이 활성화됨
userpassChanged();
}
}
private void userpassChanged(){
if(textUser.getText().length() > 0) { //ID 글자가 입력되면
textPass.setColleagueEnabled(true);//PASS 입력 활성
if(textPass.getText().length() > 0 ){//만약 PASS에 글자가 입력되면
buttonOk.setColleagueEnabled(true);//OK버튼 활성
}else{//아니면 계속 비활성
buttonOk.setColleagueEnabled(false);
}
}else{//ID글자가 입력되지 않으면
textPass.setColleagueEnabled(false);//PASS 비활성
buttonOk.setColleagueEnabled(false);//OK버튼 비활성
}
}
@Override
public void actionPerformed(ActionEvent arg0) {//OK나 CANCEL 버튼이 눌리면
// TODO Auto-generated method stub
System.out.println(arg0.toString());//출력하고
System.exit(0);//끝냄
}
}
Main 클래스
package kch;
public class Main {
static public void main(String args[]){
new LoginFrame("Mediator Sample");
}
}
결과화면.
이번 패턴의 핵심은 많은 사람들이 각자 잘하는 일이 있는데 그것을 중재하는 사람이 한명이 있어서 그사람이 너는 이것을 하고 너는 저것을 하라고 명령합니다.
@Override
public void colleagueChanged() {
// TODO Auto-generated method stub
if(checkGuest.getState()){//라디오버튼 상태 추적 게스트일경우는
textUser.setColleagueEnabled(false);//ID입력 비활성
textPass.setColleagueEnabled(false);//PASS입력 비활성
buttonOk.setColleagueEnabled(true);//OK버튼 비활성
}else{//게스트가 아닐 경우.
textUser.setColleagueEnabled(true);//ID입력이 활성화됨
userpassChanged();
}
}
명령하는 부분이 윗부분입니다. textUser, buttonOk에게 상태를 어떻게 바꾸라고 명령하고 있습니다. 그리고 각자 할 줄아는 일인setColleagueEnabled를 수행하게 되구요.
이렇게 구현하면 textUser, textPass등을 재이용할 수 있다는 장점이 있습니다.
그러나 프레임을 더 추가 시켜서 로그인화면 다음에 메인화면이 나온다면 그때부터는 새로 클래스를 만들어야한다는 단점이 있습니다.
'프로그래밍 > 자바 디자인패턴' 카테고리의 다른 글
디자인패턴 Flyweight 패턴 (0) | 2012.08.15 |
---|---|
디자인패턴 State 패턴 (0) | 2012.08.14 |
디자인 패턴 Memento 패턴 (0) | 2012.08.13 |
디자인패턴 Observer 패턴 (0) | 2012.08.10 |
디자인패턴 Facade 패턴 (0) | 2012.08.06 |
디자인 패턴 ProtoType패턴 (0) | 2012.08.03 |
디자인 패턴 singleton 패턴 (0) | 2012.08.03 |
디자인 패턴 Factory Method 패턴 (0) | 2012.08.03 |