设计模式:仲裁者(Mediator)模式
设计模式:仲裁者(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)模式的更多相关文章
- Mediator模式(仲裁者设计模式)
Mediator ? Mediator的意思是"仲裁者""中介者".一方面,当发生麻烦事情的时候,通知仲裁者:当发生涉及全体组员的事情时,也通知仲裁者.当仲裁者 ...
- 设计模式--中介(Mediator)模式
时隔很长一段时,现在又重温设计模式,上个星期学习<设计模式--代理(Proxy)模式>http://www.cnblogs.com/insus/p/4128814.html. 温故而知新, ...
- 乐在其中设计模式(C#) - 中介者模式(Mediator Pattern)
原文:乐在其中设计模式(C#) - 中介者模式(Mediator Pattern) [索引页][源码下载] 乐在其中设计模式(C#) - 中介者模式(Mediator Pattern) 作者:weba ...
- Java设计模式(16)中介模式(Mediator模式)
Mediator定义:用一个中介对象来封装一系列关于对象交互行为. 为何使用Mediator模式/中介模式 各个对象之间的交互操作非常多,每个对象的行为操作都依赖彼此对方,修改一个对象的行为,同时会涉 ...
- C++设计模式 之 “接口隔离” 模式:Facade、Proxy、Mediator、Adapter
“接口隔离”模式 在组建构建过程中,某些接口之间之间的依赖常常会带来很多问题.甚至根本无法实现.采用添加一层间接(稳定)接口,来隔离本来相互紧密关联的接口是一种常见的解决方案. 典型模式 #Facad ...
- 设计模式16:Mediator 中介者模式(行为型模式)
Mediator 中介者模式(行为型模式) 依赖关系的转化 动机(Motivation) 在软件构建过程中,经常出现多个对象互相关联交互的情况,对象之间经常会维持一种复杂的应用关系,如果遇到一些需求的 ...
- 设计模式之中介者模式(Mediator)摘录
23种GOF设计模式一般分为三大类:创建型模式.结构型模式.行为模式. 创建型模式抽象了实例化过程.它们帮助一个系统独立于怎样创建.组合和表示它的那些对象.一个类创建型模式使用继承改变被实例化的类,而 ...
- 设计模式(十六)Mediator模式
在实际的工作小组的交流过程是,组员向仲裁者报告,仲裁者向组员下达指示,组员之间不再互相询问和指示.Mediator模式是指,当发生麻烦事情的时候,通知仲裁者:当发生涉及全体组员的事情时,也通知仲裁者. ...
- 大熊君说说JS与设计模式之------中介者模式Mediator
一,总体概要 1,笔者浅谈 我们从日常的生活中打个简单的比方,我们去房屋中介租房,房屋中介人在租房者和房东出租者之间形成一条中介.租房者并不关心他租谁的房.房东出租者也不关心他租给谁.因为有中介的存在 ...
- 23种设计模式之中介者模式(Mediator)
中介者模式是一种对象的行为型模式,通过一个中介对象来封装一系列的对象交互.中介者使得各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互.中介者对象的存在保证了对象结构上的稳 ...
随机推荐
- how to be an efficient man
"This Monday I was invited to do a presentation on this Friday, and today is Friday. I am going ...
- Android AsyncTask异步加载WebAPI
之前做的程序一直存在很多问题,因为需要加载的Activity需要从网络加载数据.并没有完全正确的使用异步的方法去加载! 之前用的虽然是AsyncTask,但是在加载完成的时候还是并没有使用AsyncT ...
- 关于JS闭包
今天在敲代码的时候,发现很多JQ插件在写闭包的时候都会用到下面的写法: (function ($) { ... })(jQuery); 一时的好奇心驱使,我研究起了这一写法来.大家都知道,在 $ 没有 ...
- CentOS7下Django安装
Django安装介绍 安装环境: CentOS7 安装Django比较简单,但需要安装其依赖的东西,还是需要一定时间的.我使用的环境是CentOS Linux release 7.3.1611. 内核 ...
- train,dev,test数据集作用
train为训练语料,用于模型训练: dev为开发集,用于模型参数调优: test用于测试
- WEBPACK & BABEL 打包项目
本文首发于 BriFuture's Blog. 最近在用 Vue 重写之前的一个项目 Compass,这个项目以前是用 QML + JavaScript 在 Qt 平台上搭建的.这是我本科毕设时做的一 ...
- WAMP环境配置-PHP安装
我这次环境配置安装的是php-5.6.25版本! (最近我在反复安装PHP的时候出现了一个问题,httpd.conf加载php5apache2_4.dll出现错误,怎么修改都不行,此时我安装的是VC1 ...
- 企业为什么需要实施BPM?
背景:众所周知,近几年企业信息化发展迅速,业务管理系统从大到小,数量众多,如ERP,SCM,PLM,CRM,EHR,OA,BI…… 等,企业的管理人员进行管理的主要手段是通过各个业务系统获得各种管理报 ...
- SQL练习(一)
查找今天过生日的同学 这里表中已经存储了生日,所以思路是取出date_birth去今天的日期相比较 SELECT NAME,date_birth FROM org_mhi_studentfiles W ...
- Filter的常见应用
1.字符编码过滤器 实现功能,在a.jsp中填写用户名提交到b.jsp,在b.jsp中读取参数名. a.jsp <body> <form action="encoding/ ...