프로그래밍/자바 디자인패턴

디자인패턴 Mediator 패턴

가카리 2012. 8. 9. 22:00
반응형

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등을 재이용할 수 있다는 장점이 있습니다.

 

그러나 프레임을 더 추가 시켜서 로그인화면 다음에 메인화면이 나온다면 그때부터는 새로 클래스를 만들어야한다는 단점이 있습니다.