中介者(Mediator)模式--------------只有一个仲裁者

》》组员向仲裁者报告,仲裁者向组员下达指示。组员之间不再相互

      询问和相互指示。

》》在该模式中:一方面,当发生麻烦事情的时候,通知仲裁者;当

     发生涉及全体组员的事情时,也通知仲裁者。当仲裁者下达指示时,

     组员会立即执行。团队组员之间不再互相沟通并私自做出决定,而

    是发生任何事情都向仲裁者报告。另一方面,仲裁者站在整个团队

    的角度对组员上报的事情做出决定。

------------------下面的示例程序是一个GUI 应用程序,它展示了一个登

    陆对话框,用户在其中输入正确的用户名和密码后可以登陆。

》》要调整多个对象之间的关系时,就需要用到 Mediator 模式了。

     即不让各个对象之间互相通信,而是增加一个仲裁者角色,让

    他们各自与仲裁者通信。然后,将控制显式的逻辑处理交给仲

    裁者负责。

》》登陆对话框:

        

       对话框的使用方法如下:

       *** 可以选择作为游客访问(Guest)  或是作为用户登陆(Login)

       *** 作为用户登陆时,需要输入正确的用户名(Username)和密码(Password)

       *** 点击OK按钮可以登陆,点击 Cancel 按钮可以取消登陆

            (在示例程序中我们不会真正登陆,而是在按下按钮后就退出程序)

    具体的要求:

      *** 如果选择作为游客访问,那么禁用用户名输入框和密码输入框,使用户无法输入

      *** 如果选择作为用户登陆,那么启用用户名输入和密码输入框,使用户可以输入

      *** 如果在用户名输入框中一个字符都没有输入,那么禁用密码输入框,使用户无法

           输入密码

      *** 如果用户名输入框中输入至少一个字符,那么启用密码输入框,使用户可以输入

           密码(当然,如果选择作为游客访问,那么密码框依然是禁用状态)

      *** 只有当用户名输入框和密码输入框中都至少输入一个字符后,OK 按钮才处于启

           用状态,可以被按下。用户名输入框或密码输入框中一个字符都没有被输入的时

           候,禁用 OK  按钮,使其不可被按下(当然,如果选择作为游客访问,那么OK

          按钮总是处于启用状态)

      *** Cancel 按钮总是处于启用状态,任何时候都可以按下该按钮。

-----------------------------------------

     《示例程序的类图》

      

》》Mediator 接口:

       package mediator;
/*
 * 该接口是表示仲裁者的接口
 */
public interface Mediator {
/*
* 生成 Mediator 要管理的组员,在示例程序中,createColleagues()
* 会生成对话框中的按钮和文本输入框等控件
*/
public abstract void createColleagues();
/*
* colleagueChanged()该方法会被各个 Colleague 组员调用。
* 它的作用是让组员可以向仲裁者进行报告。在本例 中,当单选按钮和文本
* 输入框的状态发生变化时,该方法会被调用。
*/
public abstract void colleagueChanged();


}

》》Colleague 接口:

       package mediator;
/*
 * 该接口表示的是向仲裁者进行报告的组员的接口
 */


public interface Colleague {
/*
* 该方法的作用是告知组员“我是仲裁者,有事请报告我”。向该方法中传递的参数是
* 仲裁者的实例,之后在需要向仲裁者报告时(即调用colleagueChanged() )
* 会用到该实例
*/
public abstract void setMediator(Mediator mediator);
/*
* 该方法的作用是告知组员仲裁者所下达的指示。参数 enabled 如果为 true ,
* 就表示自己需要变为“启动状态”;如果是 false ,则表示自己需要变为
* “禁止状态”。这个方法表明,究竟是变为“启动状态”还是变为“禁止状态”,
* 并非由组员自己决定,而是由仲裁者来决定。
*/
public abstract void setColleagueEnabled(boolean enabled);


}

》》ColleagueButton 类:

       package mediator;


import java.awt.Button;
/*
 * 按钮
 */
public class ColleagueButton extends Button implements Colleague {
private Mediator mediator;
//给该按钮指定标签
public ColleagueButton(String string){
super(string);
}
//保存该按钮的仲裁者
public void setMediator(Mediator mediator) {
this.mediator = mediator;
}
    //Mediator 下达启用/禁止的指示
public void setColleagueEnabled(boolean enabled) {
setEnabled(enabled);
}


}

》》ColleagueTextField  类:

        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 Colleague,TextListener {
private Mediator mediator;
//单行文本初始化(使用构造函数 )
public ColleagueTextField(String string , int columns){
super(string , columns);
}
    //保存该单行文本的仲裁者
public void setMediator(Mediator mediator) {
this.mediator = mediator;
}


//Mediator 下达启用/禁用的指示
public void setColleagueEnabled(boolean enabled) {
setEnabled(enabled);
//当启用时,文本框的背景是白色;当禁用时,文本框的背景是灰色
setBackground(enabled? Color.white:Color.lightGray);
}
/*
* java.awt.event.TextListener 接口里面的方法
* 当文字发生变化时 通知 仲裁者 Mediator

* 当文本内容发生变化时,AWT 框架会调用该方法
*/
public void textValueChanged(TextEvent e){
mediator.colleagueChanged();
}


}

》》ColleagueCheckbox 类:

         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;
//复选按钮的构造函数,CheckboxGroup 类用于集合 Checkbox 按钮集。
public ColleagueCheckbox(String caption , CheckboxGroup group , boolean state){
super(caption , group , state);
}
     
//设置该复选框的仲裁者
public void setMediator(Mediator mediator){
this.mediator = mediator;
}

//Meidator 下达启用/禁用指示
public void setColleagueEnabled(boolean enabled){
setEnabled(enabled);
}
/*
* java.awt.event.ItemListener  接口中的方法
* 在用户已选定或取消选定某项时调用。
*/
public void itemStateChanged(ItemEvent e) {
mediator.colleagueChanged();


}


}

》》 LoginFrame 类:

         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;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;


public class LoginFrame extends Frame implements ActionListener, Mediator,
WindowListener{
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.LIGHT_GRAY);
//使用布局管理器生成 4*2 窗格
setLayout(new GridLayout(4,2));
//给该窗口增加一个窗口监听器
this.addWindowListener(this);
//生成各个 Colleague
createColleagues();
//配置
add(checkGuest);
add(checkLogin);
add(new Label("Username:"));
add(textUser);
add(new Label("Password"));
add(textPass);
add(buttonOk);
add(buttonCancel);
//设置初始的启用、禁用状态
colleagueChanged();
//显示
pack();
setVisible(true);

}

//生成各个 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);



}


//接收来自于 Colleague 的通知然后判断各 Colleague 的启用/禁用状态
public void colleagueChanged() {
/*
*当 Guest 按钮是开着的,那用户名和密码框就是关闭的,而ok 按钮是开着的
*/
//Guest 模式
if(checkGuest.getState()){
textUser.setColleagueEnabled(false);
textPass.setColleagueEnabled(false);
buttonOk.setColleagueEnabled(true);
}else{
//Login 模式
textUser.setColleagueEnabled(true);
userpassChanged();
}



}
/*
* 当 textUser 或 textPass 文本输入框中的文字发生变化时,
* 判断各  Colleague 的启用 / 禁用状态
*/
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);
}

}
     
/*
* java.awt.event.ActionListener 接口
* 里面的方法
*/

public void actionPerformed(ActionEvent e) {
System.out.println(e.toString());
System.exit(0);


}

//java.awt.event.WindowListener 接口中的方法


@Override
public void windowOpened(WindowEvent e) {
// TODO Auto-generated method stub

}


@Override
public void windowClosing(WindowEvent e) {
System.exit(0);

}


@Override
public void windowClosed(WindowEvent e) {
// TODO Auto-generated method stub

}


@Override
public void windowIconified(WindowEvent e) {
// TODO Auto-generated method stub

}


@Override
public void windowDeiconified(WindowEvent e) {
// TODO Auto-generated method stub

}


@Override
public void windowActivated(WindowEvent e) {
// TODO Auto-generated method stub

}


@Override
public void windowDeactivated(WindowEvent e) {
// TODO Auto-generated method stub

}


}

》》Main 类-----》测试程序

      package mediator;


public class Main {
public static void main(String[] args){
new LoginFrame("Mediator Sample");
}


}

-----------------------------------------------

          《Mediator 模式中的登场角色》

           **** Mediator (仲裁者、中介者)

                   Mediator 角色负责定义与 Colleague 角色进行通信和做出决定的接口。

               在示例程序中,由 Mediator 接口扮演此角色。

           **** ConcreteMediator  (具体的仲裁者、中介者)

                   ConcreteMediator 角色负责实现 Mediator 角色的接口,负责实际做出

               决定。在示例程序中,由 LoginFrame 类扮演此角色。

           **** Colleague (同事)

                   Colleague 角色负责定义与 Mediator 角色进行通信的接口。在示例程序

               中,由 Colleague 接口扮演此角色。

           **** ConcreteColleague (具体的同事)

                   ConcreteColleague 角色负责定义实现 Colleague 角色的接口。在示例

              程序中,由 ColleagueButton 类、ColleagueTextField 类 和

               ColleagueCheckbox  类扮演此角色。

-----------------------------------------------

           《扩展思路要点》

             1.当发生分散灾难时

             2.通信线路的增加

             3.哪些角色可以复用

                      上面的示例程序中的 ConcreteColleague 角色可以复用,但是

                ConcreteMediator 角色很难复用。

------------------------------------------------

            《相关的设计模式》

              **** Facade 模式

              **** Observer 模式

猜你喜欢

转载自blog.csdn.net/lierming__/article/details/79679742
今日推荐