【笔记整理】图解设计模式 | 第16章 Mediator模式(只有一个仲裁者)

【笔记整理】图解设计模式 | 导航

【笔记整理】图解设计模式 | 第16章 Mediator模式(只有一个仲裁者)_第1张图片


定义

  • 组员向仲裁者报告,仲裁者向组员下达指示。
  • 当发生麻烦事情的时候,通知仲裁者;当发生涉及全体组员的事情时,也通知仲裁者。
  • 当仲裁者下达指示时,组员会立即执行。团队组员之间不再互相沟通并私自做出决定,而是发生任何事情都向仲裁者报告。
  • 另一方面,仲裁者站在整个团队的角度上对组员上报的事情做出决定。

Mediator模式中的登场角色

  • Mediator(仲裁者、中介者)

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

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

       ConcreteMediator角色负责实现Mediator角色的接口(API),负责实际做出决定。

  • Colleague(同事)

       Colleague角色负责定义与Mediator角色进行通信的接口(API)。

  • ConcreteColleague(具体的同事)

       ConcreteColleague角色负责实现Colleague角色的接口(API)。


Mediator模式的类图

【笔记整理】图解设计模式 | 第16章 Mediator模式(只有一个仲裁者)_第2张图片


拓展思路的要点

  • 当发生分散灾难时

       面向对象编程可以帮助我们分散处理,避免处理过于集中,也就是说可以“分而治之”。

       但有时候,把处理分散在各个类中是不明智的。如果只是将应当分散的处理分散在各个类中,但是没有将应当集中的处理集中起来,那么这些分散的类最终只会导致灾难。

  • 通信线路的增加

       A和B,相互通信线路有两条。

       A、B和C,相互通信线路有6条。

       A、B、C和D,相互通信线路有12条。

       ......

       如果存在很多相互通信的实例,那么程序结构会变得非常复杂。

       如果实例很少就不需要Mediator模式了吗?需要考虑的是,即使最初实例很少,很可能随着需求变更实例数量会慢慢变多,迟早会暴露出问题。

  • 哪些角色可以复用

       ConcreteColleague角色可以复用(原因:内部无逻辑),但ConcreteMediator角色很难复用(原因:逻辑集中)。

       依赖于特定应用程序就意味着难以复用。


相关的设计模式

  • Facade模式(第15章)

       在Mediator模式中,Mediator角色与Colleague角色进行交互。

       而在Facade模式中,Facade角色单方面地使用其他角色来对外提供高层接口(API)。因此,可以说Mediator模式是双向的,而Facade模式是单向的。

  • Observer模式(第17章)

       有时会使用Observer模式来实现Mediator角色与Colleague角色之间的通信。


代码

  • Mediator(仲裁者、中介者)
public interface Mediator {

	// 生成Mediator要管理的组员
	void createColleagues();

	// 被各个Colleague组员调用,当组员状态发生变化时,该方法会被调用
	void colleagueChanged();
}
  • ConcreteMediator(具体的仲裁者,中介者)
public class LoginFrame extends Frame implements ActionListener, Mediator {

	private static final long serialVersionUID = 1L;

	private ColleagueCheckbox checkGuest;
	private ColleagueCheckbox checkLogin;
	private ColleagueTextField textUser;
	private ColleagueTextField textPass;
	private ColleagueButton buttonOk;
	private ColleagueButton buttonCancel;

	// 构造函数
	// 生成并配置各个Colleague后,显示对话框
	@SuppressWarnings("deprecation")
	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
	@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的通知然后判断各colleague的启用/禁用状态
	@Override
	public void colleagueChanged() {
		if (checkGuest.getState()) { // Guest mode
			textUser.setColleagueEnabled(false);
			textPass.setColleagueEnabled(false);
			buttonOk.setColleagueEnabled(false);
		} else { // Login mode
			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);
		}
	}

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

}
  • Colleague(同事)
public interface Colleague {

	void setMediator(Mediator mediator);

	// 告知组员仲裁者所下达的指示
	void setColleagueEnabled(boolean enabled);
}
  • ConcreteColleague(具体的同事)
import java.awt.Button;

public class ColleagueButton extends Button implements Colleague {

	private static final long serialVersionUID = 1L;

	@SuppressWarnings("unused")
	private Mediator mediator;

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

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

	@Override
	public void setColleagueEnabled(boolean enabled) { // Mediator下达启动/禁用的指示
		setEnabled(enabled);
	}

}
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 = 1L;

	private Mediator mediator;

	public ColleagueCheckbox(String caption, CheckboxGroup group, boolean state) { // 构造函数
		super(caption, group, state);
	}

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

	@Override
	public void setColleagueEnabled(boolean enabled) { // Mediator下达启用/禁用指示
		setEnabled(enabled);
	}

	@Override
	public void itemStateChanged(ItemEvent e) { // 当状态发生变化时通知Mediator
		mediator.colleagueChanged();
	}

}
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 = 1L;

	private Mediator mediator;

	public ColleagueTextField(String text, int columns) { // 构造函数
		super(text, columns);
	}

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

	@Override
	public void setColleagueEnabled(boolean enabled) { // Mediator下达启用/禁用的指示
		setEnabled(enabled);
		setBackground(enabled ? Color.white : Color.lightGray);
	}

	@Override
	public void textValueChanged(TextEvent e) { // 当文字发生变化时通知Mediator
		mediator.colleagueChanged();
	}

}
  • Main
public class Main {

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

}

注:博客中的图片来自网上。

你可能感兴趣的:(设计模式)