LoginSignup
0
0

More than 3 years have passed since last update.

Mediatorパターン

Posted at

Mediatorパターンとは

「相談役」を用意するパターン。
仕事を行うメンバーは、全体に波及する出来事がおきた時相談役に知らせる。
また、相談役からの指示には素直に応じる。
相談役は、メンバーからの知らせを元に大局的な判断を行い、
各メンバーに指示をだす。

Mediator(調停者、仲介者)の役

Colleague役と通信を行って、調整を行うためのインターフェースを定める。

package mediator;

public interface Mediator {
    // このMediatorが管理するメンバーを生成する
    public abstract void createColleagues();
    // 相談役への相談
    public abstract void collegueChanged();
}

ConcreteMediator(具体的な調停者、仲介者)の役

Mediator役のインターフェースを実装し、実際の調整を行う。

package mediator;

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 {
    private ColleagueCheckBox checkGuest;
    private ColleagueCheckBox checkLogin;
    private ColleagueTextField textUser;
    private ColleagueTextField textPass;
    private ColleagueButton buttonOk;
    private ColleagueButton buttonCancel;

     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("User name:"));
         add(textUser);
         add(new Label("Password:"));
         add(textPass);
         add(buttonOk);
         add(buttonCancel);
         // 有効/無効の初期設定
         collegueChanged();
         // 表示
         pack();
         show();
    }

    @Override
    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);
    }

    // Colleagueからの通知で有効/無効を判定する
    @Override
    public void collegueChanged() {
        if (checkGuest.getState()) {
            // Guestモード
            textPass.setColleagueEnabled(true);
            if (textPass.getText().length() > 0) {
                buttonOk.setEnabled(true);
            } else {
                buttonOk.setEnabled(false);
            }
        } else {
            // Loginモード
            textPass.setColleagueEnabled(false);
            buttonOk.setColleagueEnabled(false);
        }
    }

    // textUserまたはtextPassの変更があった
    // 各Colleagueの有効/無効を判定する
    @Override
    public void actionPerformed(ActionEvent e) {
        System.out.println(e);
        System.exit(0);
    }
}

Colleague(同僚)の役

Mediator役と通信を行うインターフェースを定める。

package mediator;

public interface Colleague {
    public abstract void setMediator(Mediator mediator);
    // 相談役からやってくる指示に該当
    public abstract void setColleagueEnabled(boolean enabled);
}

ConcretrColleague(具体的同僚)の役

Colleague役のインターフェースを実装する。

package mediator;

import java.awt.Button;
/**
 * LoginFrameクラス(Mediatorインターフェース)と協調動作を行う
 *
 */
public class ColleagueButton extends Button implements Colleague{
    private Mediator mediator;

    public ColleagueButton(String caption) {
        super(caption);
    }

    @Override
    public void setMediator(Mediator mediator) {
        this.mediator = mediator;
    }

    // Mediatorから有効/無効が指示される
    @Override
    public void setColleagueEnabled(boolean enabled) {
        setEnabled(enabled);
    }
}
package mediator;

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 {
    private Mediator mediator;

    public ColleagueTextField(String text, int columns) {
        super(text, columns);
    }

    @Override
    public void setMediator(Mediator mediator) {
        this.mediator = mediator;
    }

    @Override
    public void setColleagueEnabled(boolean enabled) {
        setEnabled(enabled);
        setBackground(enabled ? Color.white : Color.lightGray);
    }

    // 文字列が変化した場合Mediatorに通知
    public void textValueChanged(TextEvent e) {
        mediator.collegueChanged();
    }

}
package mediator;

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 {
    private Mediator mediator;

     public ColleagueCheckBox(String caption, CheckboxGroup group, boolean state) {
         super(caption, group, state);
    }

    @Override
    public void setMediator(Mediator mediator) {
        this.mediator = mediator;
    }

    @Override
    public void setColleagueEnabled(boolean enabled) {
        setEnabled(enabled);
    }

    @Override
    public void itemStateChanged(ItemEvent e) {
        mediator.collegueChanged();
    }
}

上記のプログラムでは、ボタンの活性、非活性の判断を相談役であるLoginFrameクラスが行っている。
各メンバー(ColleagueButton,TextField,CheckBox)は相談役に知らせているだけで、判断は相談役に任せている。

こちらを参考にさせていただきました。
増補改訂版Java言語で学ぶデザインパターン入門

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0