设计模式:仲裁者(Mediator)模式

一、前言

    Mediator模式又称为仲裁者模式或者中介者模式,所起的作用是仲裁和中介,帮助其它类之间进行交流。在仲裁者模式之中,我们要明确两个概念,那就是仲裁者(Mediator)和组员(Colleague),不管组员有什么事情,都会向仲裁者汇报,仲裁者会根据全局的实际情况向其他Colleague作出指示,共同完成一定的逻辑功能。 

二、代码

 Mediator接口:(仲裁者接口)

 package zyr.dp.mediator;

 public interface Mediator {
public abstract void createColleagues();
public abstract void ColleagueChanged();
}

 Colleague 组员接口:

 package zyr.dp.mediator;

 public interface Colleague {
public abstract void setMediator(Mediator mediator);
public abstract void setColleagueEnable(boolean enable);
}

 ColleagueButton实现类:

 package zyr.dp.mediator;

 import java.awt.Button;

 public class ColleagueButton extends Button implements Colleague {

     private static final long serialVersionUID = 1309335015058337931L;

     public ColleagueButton(String caption){
super(caption);
} private Mediator mediator;
public void setMediator(Mediator mediator) {
this.mediator=mediator;
} public void setColleagueEnable(boolean enable) {
setEnabled(enable);
} }

 ColleagueCheckBox实现类:

 package zyr.dp.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 static final long serialVersionUID = -628547709974079324L; public ColleagueCheckBox(String caption,CheckboxGroup g,boolean b){
super(caption,g,b);
} private Mediator mediator;
public void setMediator(Mediator mediator) {
this.mediator=mediator;
} public void setColleagueEnable(boolean enable) {
setEnabled(enable); } public void itemStateChanged(ItemEvent e) {
mediator.ColleagueChanged();
} }
ColleagueTextField 实现类:
 package zyr.dp.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 static final long serialVersionUID = 8539124564669846422L; public ColleagueTextField(String text,int columns){
super(text,columns);
} private Mediator mediator;
public void setMediator(Mediator mediator) {
this.mediator=mediator;
} public void setColleagueEnable(boolean enable) {
setEnabled(enable);
setBackground( enable? Color.WHITE : Color.BLACK );
} public void textValueChanged(TextEvent e) {
mediator.ColleagueChanged();
} }
LoginFrame 实现类:
 package zyr.dp.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 static final long serialVersionUID = -509490729876024682L; private ColleagueButton buttonOK;
private ColleagueButton buttonCancel; private ColleagueCheckBox chkGuest;
private ColleagueCheckBox chkUser; private ColleagueTextField tfUser;
private ColleagueTextField tfPass; public LoginFrame(String title){
super(title);
setBackground(Color.lightGray);
setLayout(new GridLayout(4,2));
createColleagues();
add(chkGuest);
add(chkUser);
add(new Label("用户名:"));
add(tfUser);
add(new Label("密码:"));
add(tfPass);
add(buttonOK);
add(buttonCancel);
ColleagueChanged();
pack();
show();
} public void createColleagues() {
CheckboxGroup chk=new CheckboxGroup();
chkGuest=new ColleagueCheckBox("Guest",chk,true);
chkUser=new ColleagueCheckBox("User",chk,false);
buttonOK=new ColleagueButton("OK");
buttonCancel=new ColleagueButton("Cancel");
tfUser=new ColleagueTextField("",10);
tfPass=new ColleagueTextField("",10);
tfPass.setEchoChar('#'); chkGuest.setMediator(this);
chkUser.setMediator(this);
buttonOK.setMediator(this);
buttonCancel.setMediator(this);
tfUser.setMediator(this);
tfPass.setMediator(this); chkGuest.addItemListener(chkGuest);
chkUser.addItemListener(chkUser);
buttonOK.addActionListener(this);
buttonCancel.addActionListener(this);
tfUser.addTextListener(tfUser);
tfPass.addTextListener(tfPass); } public void ColleagueChanged() { if(chkGuest.getState()){
tfUser.setColleagueEnable(false);
tfPass.setColleagueEnable(false);
buttonOK.setColleagueEnable(true);
}else{
tfUser.setColleagueEnable(true);
userPassChanged();
}
} private void userPassChanged() {
if(tfUser.getText().length()>0){
tfPass.setColleagueEnable(true);
if(tfPass.getText().length()>0){
buttonOK.setColleagueEnable(true);
}else{
buttonOK.setColleagueEnable(false);
}
}else{
tfPass.setColleagueEnable(false);
buttonOK.setColleagueEnable(false);
} } public void actionPerformed(ActionEvent e) {
System.out.println(e.toString());
System.exit(0);
} }
Main 方法:
 package zyr.dp.mediator;

 public class Main {

     public static void main(String[] args) {
LoginFrame login=new LoginFrame("仲裁者模式");
} }

 运行结果:

  游客访问,不用输入用户名和密码,因此禁用。

  会员访问,只有输入用户名之后才能输入密码,用户名可用,密码暂不能用,登录按钮OK不可用。

 会员访问,输入用户名之后可以输入密码,用户名可用,密码也可用,登录按钮OK不可用

 会员访问,输入用户名和密码之后,登录按钮OK可用

 点击登录按钮OK:

    分析:这些组件(按钮、文本框、单选框)每一个发生改变之后就要导致其他组件发生改变,比如用户名文本框改变,密码文本框也要相应改变,如果我们直接让这两个文本框之间产生交互,我们应该怎么样写代码呢?我们可能在用户名文本框发生改变的函数中通知密码文本框,让密码文本框可用,那么我们需要能够得到密码文本框的对象,这必定是一件非常难以做到的事情,同样的,密码文本框的改变还要使得按钮发生改变,我们势必会将密码文本框和按钮之间再次建立联系(传递参数),这也是一件非常复杂的事情,同样的单选框发生改变,两个文本框和一个按钮都要发生改变,这又要在单选框之中得到这些组件的对象,然后才能改变这些组件的状态,但是单选框都有两个,来自于同一个类,我们要怎么识别呢,可能还要通过一定的方法得到单选框的ID,这是极其复杂的,最让人难以接受的是,如果需求发生了改变,比如又增加了一个控件,剩余的所有组件的代码都要修改,而这些代码之间本就混乱无比,再次修改就更让人难以接受了,因此这不是一个好的办法,甚至可以说是一个非常差的解决办法。

    那么有什么好的解决办法吗?那就是将这些复杂的逻辑操作独立出来,新创建一个类,在每个控件的状态发生改变的时候就能通过某种方式通知到这个类,让这个类改变这些控件的状态,这样说来这个新的类应该持有这些控件的引用,这样才能委托这些控件去改变自己的状态,同时这些控件要想通知这个新的类,那就要持有这个类(或其父类)的引用,这样才能委托这个新的类去实现所有状态的改变。这样我们的思路就清晰明了了,如果一个再增加一个新的控件,需要添加逻辑,我们只需要修改仲裁者的方法,就可以做到全局的掌控,达到了修改最少的代码来扩展程序的行为,因此仲裁者模式非常的重要和实用。

三、总结

   对我们的程序而言,仲裁者模式适合于某一个部分发生改变就会导致其他部分做出相应的改变的情况,我们将这种变换的规律抽象出来,变成仲裁者,从而很好的协商各个部分,当组员有问题的时候(状态发生改变),直接告诉仲裁者,不与其他组员打交道,让仲裁者负责这些繁琐的事务,这样条理就很清晰了,因此仲裁者也成为中介者,可以想象很多人要去租房,很多人要把房子出租,如果私下里面去商量,既浪费时间,又很难找到对方,通过中介这个对象,它收集了很多的租房和出租房的信息,这样就能很快的找到最适合的房子。由此可见生活就是最好的设计模式。仲裁者模式对于代码的修改(很容易定位错误)、新的成员的加入、代码的复用(组员部分可以复用,仲裁者部分不易复用)都有着一定的简化,将该集中处理的集中起来,将该分散的分散出去,无疑是一种好的设计模式。对比于外观模式Facade,仲裁者需要和组员沟通,是双向的,而外观模式facade角色只是对其他角色进行整合,是单向的。设计模式至今我们已经研究了16种了,这其中很多设计模式都是有着关联的,同样也有着不同之处,但是都和实际问题是分不开的,设计模式是实际问题的抽象和解决方法,为了提高可扩展性和组件化,实际问题是设计模式的来源和最终归宿。

  程序代码

设计模式:仲裁者(Mediator)模式的更多相关文章

  1. Mediator模式(仲裁者设计模式)

    Mediator ? Mediator的意思是"仲裁者""中介者".一方面,当发生麻烦事情的时候,通知仲裁者:当发生涉及全体组员的事情时,也通知仲裁者.当仲裁者 ...

  2. 设计模式--中介(Mediator)模式

    时隔很长一段时,现在又重温设计模式,上个星期学习<设计模式--代理(Proxy)模式>http://www.cnblogs.com/insus/p/4128814.html. 温故而知新, ...

  3. 乐在其中设计模式(C#) - 中介者模式(Mediator Pattern)

    原文:乐在其中设计模式(C#) - 中介者模式(Mediator Pattern) [索引页][源码下载] 乐在其中设计模式(C#) - 中介者模式(Mediator Pattern) 作者:weba ...

  4. Java设计模式(16)中介模式(Mediator模式)

    Mediator定义:用一个中介对象来封装一系列关于对象交互行为. 为何使用Mediator模式/中介模式 各个对象之间的交互操作非常多,每个对象的行为操作都依赖彼此对方,修改一个对象的行为,同时会涉 ...

  5. C++设计模式 之 “接口隔离” 模式:Facade、Proxy、Mediator、Adapter

    “接口隔离”模式 在组建构建过程中,某些接口之间之间的依赖常常会带来很多问题.甚至根本无法实现.采用添加一层间接(稳定)接口,来隔离本来相互紧密关联的接口是一种常见的解决方案. 典型模式 #Facad ...

  6. 设计模式16:Mediator 中介者模式(行为型模式)

    Mediator 中介者模式(行为型模式) 依赖关系的转化 动机(Motivation) 在软件构建过程中,经常出现多个对象互相关联交互的情况,对象之间经常会维持一种复杂的应用关系,如果遇到一些需求的 ...

  7. 设计模式之中介者模式(Mediator)摘录

    23种GOF设计模式一般分为三大类:创建型模式.结构型模式.行为模式. 创建型模式抽象了实例化过程.它们帮助一个系统独立于怎样创建.组合和表示它的那些对象.一个类创建型模式使用继承改变被实例化的类,而 ...

  8. 设计模式(十六)Mediator模式

    在实际的工作小组的交流过程是,组员向仲裁者报告,仲裁者向组员下达指示,组员之间不再互相询问和指示.Mediator模式是指,当发生麻烦事情的时候,通知仲裁者:当发生涉及全体组员的事情时,也通知仲裁者. ...

  9. 大熊君说说JS与设计模式之------中介者模式Mediator

    一,总体概要 1,笔者浅谈 我们从日常的生活中打个简单的比方,我们去房屋中介租房,房屋中介人在租房者和房东出租者之间形成一条中介.租房者并不关心他租谁的房.房东出租者也不关心他租给谁.因为有中介的存在 ...

  10. 23种设计模式之中介者模式(Mediator)

    中介者模式是一种对象的行为型模式,通过一个中介对象来封装一系列的对象交互.中介者使得各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互.中介者对象的存在保证了对象结构上的稳 ...

随机推荐

  1. linux下定时任务的工具crontab的用法

    Linux计划任务工具cron用法详解 linux下大名鼎鼎的计划任务工具crontab的使用介绍baidu.google上多得让人眼花缭乱,本着“天下文章一大抄”的觉悟,加上本人日常工作中总结的使用 ...

  2. java实现HTTP请求的三种方式

    目前JAVA实现HTTP请求的方法用的最多的有两种:一种是通过HTTPClient这种第三方的开源框架去实现.HTTPClient对HTTP的封装性比较不错,通过它基本上能够满足我们大部分的需求,Ht ...

  3. React 同构开发(二)

    React 同构 所谓同构,简单的说就是客户端的代码可以在服务端运行,好处就是能极大的提升首屏时间,避免白屏,另外同构也给SEO提供了很多便利. React 同构得益于 React 的虚拟 DOM.虚 ...

  4. 快速部署简单私有云CloudStack(下)

    微信公众号:wsy535068621 继续上边的 会给出具体配置

  5. 九度oj 1003 A+B 2010年浙江大学计算机及软件工程研究生机试真题

    题目1003:A+B 时间限制:1 秒 内存限制:32 兆 特殊判题:否 提交:12812 解决:5345 题目描述: 给定两个整数A和B,其表示形式是:从个位开始,每三位数用逗号",&qu ...

  6. Memcached 查询stats及各项状态解释

    一.两个最常用状态查询(掌握第一个就完全OK了) 1)查看状态:printf “stats\r\n” |nc 127.0.0.1 11211      2)模拟top命令查看状态:watch “ech ...

  7. angular-ui-router动态加载模块

    1.定义index.html主页,对于通用的js就不用require依赖加载了,其中main.js作为主模块,用require添加系统路由模块. <!DOCTYPE html> <h ...

  8. 巧用CheckedTextView完成自定义radiobutton的listview

    因为要用自定义图片的radiobutton的listview,最开始想自己重新写BaseAdapter,重新定义BaseAdapter中的每个list的item.总之android提供了太多方便的控件 ...

  9. 图像的点运算----底层代码与Halcon库函数

    最基本的图像分析工具----灰度直方图.使用直方图辅助,可以实现4大灰度变换,包括线性灰度变换(灰度拉伸).灰度对数变换.灰度伽马变换.灰度分段线性变换:使用直方图修正技术,可以实现2大变换,包括直方 ...

  10. django-admin管理后台高级自定义

    django自带的admin后台管理系统,在很多网站中被称为django的杀手级的应用.那么django-admin的适用情形倒底有哪些呢,一般 来说对于大型的商业性的项目通常不用采用django-a ...