본문 바로가기
개발/디자인 패턴

[Java 언어로 배우는 디자인 패턴 입문] 단순화하기 16. Mediator

by hongdor 2021. 1. 13.
728x90

출처 : 책 - 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");
    }
}

 

728x90

댓글