2021年7月29日星期四

中介者模式(学习笔记)

  1. 意图

  用一个中介对象来封装一系列的对象交互。中介者是各个对象不需要显示的相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互

  2. 动机

   面向对象设计鼓励将行为分布到各个对象中。这种分布可能导致对象间有很多连接。在最坏的情况,每一个对象都知道其他对象的存在。

  虽然将一个系统分割成许多对象通常可以增强可复用性,但是对象间相互连接的激增又会降低其可复用性。大量的相互连接使得一个对象似乎不太可能在没有其他对象的支持下工作——系统表现为一个不可分割的整体。这样,对系统的任何较大改动都十分困难,因为行为被分布在许多对象中。结果是,你可能不得不定义很多子类以定制系统的行为。

  例如,考虑一个图形用户界面中对话框的实现。对话框使用一个窗口来展现一系列的窗口组件,如按钮、菜单和输入域等,如下图所示。

   

  通常对话框中的组件间存在依赖关系。例如,当一个特定的输入域为空时,某个按钮不能使用;在称为列表框的一列选项中一个表目可能会改变输入域的内容;一旦文本出现在输入域中,其他按钮可能就变得能够使用了,这些按钮允许用户做一些操作,比如改变或删除文本所指的东西。不同的对话框会有不同的窗口组件间依赖关系。因此,即使对话框显示相同类型的窗口组件,也没办法简单的直接复用已有的窗口组件类,而必须定制以反映特定对话框的依赖关系。由于涉及多个类,用逐个生成子类的办法来定制会很冗长

·  通过将集体行为封装在一个单独的中介者对象中来避免这个问题。中介者充当一个中介以使组中的对象不在相互的显式引用。这些对象仅知道中介者的存在,从而减少了连接的数目

  例如,FontDialogDirector可作为一个对话框中的窗口组件间的中介者,充当窗口组件间通信的中转中心

  

  下面的交互图说明了各对象如何协作处理一个列表框中选项的变化:

  下面一系列事件使得一个列表框的选择被传送给一个输入域:

  1) ListBox通知中介者它被改变了

  2) 中介者从ListBox中得到选中的选项

  3) 中介者将该选项传递给EntryField

  4) 现在EnrryField已有文本,导控者使得用于发起一个动作(如"黑体","斜体")的某个按钮可用

   

  3. 适用性

  • 一组对象以定义良好但复杂的方式进行通信,产生的相互依赖关系结构混乱且难以理解
  • 一个对象引用其他很多对象并且直接与这些对象通信,导致难以复用该对象
  • 如果为了能在不同情景下复用一些基本行为,导致你需要被迫创建大量组件子类时,可使用中介者模式(所有组件间关系都被包含在中介者中,因此你无需修改组件就能方便地新建中介者类以定义新的组件合作方式)

  4. 结构

          

  5. 效果

  1)  减少子类的生成    Mediator将原本分布于多个对象间的行为集中在一起。改变这些行为只需生成Mediator的子类即可,这样各个colleague可以复用

  2)将各个Colleague解耦    Mediator有利于各Colleague间的松耦合,可以独立的改变和复用各Colleague类和Mediator类(开闭原则)

  3)简化了对象协议    用Mediator和各Colleague间的一对多交互来代替多对多交互。一对多更便于理解、维护和扩展

  4)使控制集中化    中介者模式将交互的复杂性变为中介者的复杂性。中介者封装了协议,使得它变得比任一个Colleague都复杂。这使得中介者本身变成一个难于维护的庞然大物  

  6. 代码实现  

  本例展示了如何将许多 GUI 元素组织起来, 使其在中介者的帮助下无需相互依赖就能合作

  components/Component.java

package mediator.components;import mediator.mediator.Mediator;/** * @author GaoMing * @date 2021/7/25 - 20:23 * Common component interface. */public interface Component { void setMediator(Mediator mediator); String getName();}

  components/AddButton.java

package mediator.components;import mediator.mediator.Mediator;import mediator.mediator.Note;import javax.swing.*;import java.awt.event.ActionEvent;/** * @author GaoMing * @date 2021/7/25 - 20:20 * Concrete components don't talk with each other. They have only one * communication channel–sending requests to the mediator. */public class AddButton extends JButton implements Component { private Mediator mediator; public AddButton() {  super("Add"); } @Override public void setMediator(Mediator mediator) {  this.mediator = mediator; } @Override protected void fireActionPerformed(ActionEvent actionEvent) {  mediator.addNewNote(new Note()); } @Override public String getName() {  return "AddButton"; }}

  components/DeleteButton.java

package mediator.components;import mediator.mediator.Mediator;import javax.swing.*;import java.awt.event.ActionEvent;/** * @author GaoMing * @date 2021/7/25 - 20:21 * Concrete components don't talk with each other. They have only one * communication channel–sending requests to the mediator. */public class DeleteButton extends JButton implements Component { private Mediator mediator; public DeleteButton() {  super("Del"); } @Override public void setMediator(Mediator mediator) {  this.mediator = mediator; } @Override protected void fireActionPerformed(ActionEvent actionEvent) {  mediator.deleteNote(); } @Override public String getName() {  return "DelButton"; }}

  components/Filter.java

package mediator.components;import mediator.mediator.Mediator;import mediator.mediator.Note;import javax.swing.*;import java.awt.event.KeyEvent;import java.util.ArrayList;/** * @author GaoMing * @date 2021/7/25 - 20:21 * Concrete components don't talk with each other. They have only one * communication channel–sending requests to the mediator. */public class Filter extends JTextField implements Component{ private Mediator mediator; private ListModel listModel; public Filter() {} @Override public void setMediator(Mediator mediator) {  this.mediator = mediator; } @Override protected void processComponentKeyEvent(KeyEvent keyEvent) {  String start = getText();  searchElements(start); } public void setList(ListModel listModel) {  this.listModel = listModel; } private void searchElements(String s) {  if (listModel == null) {   return;  }  if (s.equals("")) {   mediator.setElementsList(listModel);   return;  }  ArrayList<Note> notes = new ArrayList<>();  for (int i = 0; i < listModel.getSize(); i++) {   notes.add((Note) listModel.getElementAt(i));  }  DefaultListModel<Note> listModel = new DefaultListModel<>();  for (Note note : notes) {   if (note.getName().contains(s)) {    listModel.addElement(note);   }  }  mediator.setElementsList(listModel); } @Override public String getName() {  return "Filter"; }}

  components/List.java

package mediator.components;import mediator.mediator.Mediator;import mediator.mediator.Note;import javax.swing.*;/** * @author GaoMing * @date 2021/7/25 - 20:21 * Concrete components don't talk with each other. They have only one * communication channel–sending requests to the mediator. */@SuppressWarnings("unchecked")public class List extends JList implements Component { private Mediator mediator; private final DefaultListModel LIST_MODEL; public List(DefaultListModel listModel) {  super(listModel);  this.LIST_MODEL = listModel;  setModel(listModel);  this.setLayoutOrientation(JList.VERTICAL);  Thread thread = new Thread(new Hide(this));  thread.start(); } @Override public void setMediator(Mediator mediator) {  this.mediator = mediator; } public void addElement(Note note) {  LIST_MODEL.addElement(note);  int index = LIST_MODEL.size() - 1;  setSelectedIndex(index);  ensureIndexIsVisible(index);  mediator.sendToFilter(LIST_MODEL); } public void deleteElement() {  int index = this.getSelectedIndex();  try {   LIST_MODEL.remove(index);   mediator.sendToFilter(LIST_MODEL);  } catch (ArrayIndexOutOfBoundsException ignored) {} } public Note getCurrentElement() {  return (Note)getSelectedValue(); } @Override public String getName() {  return "List"; } private class Hide implements Runnable {  private List list;  Hide(List list) {   this.list = list;  }  @Override  public void run() {   while (true) {    try {     Thread.sleep(300);    } catch (InterruptedException ex) {     ex.printStackTrace();    }    if (list.isSelectionEmpty()) {     mediator.hideElements(true);    } else {     mediator.hideElements(false);    }   }  } }}

  components/SaveButton.java

package mediator.components;import mediator.mediator.Mediator;import javax.swing.*;import java.awt.event.ActionEvent;/** * @author GaoMing * @date 2021/7/25 - 20:21 * Concrete components don't talk with each other. They have only one * communication channel–sending requests to the mediator. */public class SaveButton extends JButton implements Component { private Mediator mediator; public SaveButton() {  super("Save"); } @Override public void setMediator(Mediator mediator) {  this.mediator = mediator; } @Override protected void fireActionPerformed(ActionEvent actionEvent) {  mediator.saveChanges(); } @Override public String getName() {  return "SaveButton"; }}

  components/TextBox.java

package mediator.components;import mediator.mediator.Mediator;import javax.swing.*;import java.awt.event.KeyEvent;/** * @author GaoMing * @date 2021/7/25 - 20:21 * Concrete components don't talk with each other. They have only one * communication channel–sending requests to the mediator. */public class TextBox extends JTextArea implements Component { private Mediator mediator; @Override public void setMediator(Mediator mediator) {  this.mediator = mediator; } @Override protected void processComponentKeyEvent(KeyEvent keyEvent) {  mediator.markNote(); } @Override public String getName() {  return "TextBox"; }}

  components/Title.java

package mediator.components;import mediator.mediator.Mediator;import javax.swing.*;import java.awt.event.KeyEvent;/** * @author GaoMing * @date 2021/7/25 - 20:21 * Concrete components don't talk with each other. They have only one * communication channel–sending requests to the mediator. */public class Title extends JTextField implements Component { private Mediator mediator; @Override public void setMediator(Mediator mediator) {  this.mediator = mediator; } @Override protected void processComponentKeyEvent(KeyEvent keyEvent) {  mediator.markNote(); } @Override public String getName() {  return "Title"; }}

  mediator/Mediator.java: 定义通用的中介者接口

package mediator.mediator;import javax.swing.*;import mediator.components.Component;/** * @author GaoMing * @date 2021/7/25 - 20:31 * Common mediator interface. */public interface Mediator { void addNewNote(Note note); void deleteNote(); void getInfoFromList(Note note); void saveChanges(); void markNote(); void clear(); void sendToFilter(ListModel listModel); void setElementsList(ListModel list); void registerComponent(Component component); void hideElements(boolean flag); void createGUI();}

  mediator/Editor.java: 具体中介者

package mediator.mediator;import mediator.components.*;import mediator.components.Component;import mediator.components.List;import javax.swing.*;import javax.swing.border.LineBorder;import java.awt.*;/** * @author GaoMing * @date 2021/7/25 - 20:22 * Concrete mediator. All chaotic communications between concrete components * have been extracted to the mediator. Now components only talk with the * mediator, which knows who has to handle a request. */public class Editor implements Mediator{ private Title title; private TextBox textBox; private AddButton add; private DeleteButton del; private SaveButton save; private List list; private Filter filter; private JLabel titleLabel = new JLabel("Title:"); private JLabel textLabel = new JLabel("Text:"); private JLabel label = new JLabel("Add or select existing note to proceed..."); /**  * Here the registration of components by the mediator.  */ @Override public void registerComponent(Component component) {  component.setMediator(this);  switch (component.getName()) {   case "AddButton":    add = (AddButton)component;    break;   case "DelButton":    del = (DeleteButton)component;    break;   case "Filter":    filter = (Filter)component;    break;   case "List":    list = (List)component;    this.list.addListSelectionListener(listSelectionEvent -> {     Note note = (Note)list.getSelectedValue();     if (note != null) {      getInfoFromList(note);     } else {      clear();     }    });    break;   case "SaveButton":    save = (SaveButton)component;    break;   case "TextBox":    textBox = (TextBox)component;    break;   case "Title":    title = (Title)component;    break;  } } /**  * Various methods to handle requests from particular components.  */ @Override public void addNewNote(Note note) {  title.setText("");  textBox.setText("");  list.addElement(note); } @Override public void deleteNote() {  list.deleteElement(); } @Override public void getInfoFromList(Note note) {  title.setText(note.getName().replace('*', ' '));  textBox.setText(note.getText()); } @Override public void saveChanges() {  try {   Note note = (Note) list.getSelectedValue();   note.setName(title.getText());   note.setText(textBox.getText());   list.repaint();  } catch (NullPointerException ignored) {} } @Override public void markNote() {  try {   Note note = list.getCurrentElement();   String name = note.getName();   if (!name.endsWith("*")) {    note.setName(note.getName() + "*");   }   list.repaint();  } catch (NullPointerException ignored) {} } @Override public void clear() {  title.setText("");  textBox.setText(""); } @Override public void sendToFilter(ListModel listModel) {  filter.setList(listModel); } @SuppressWarnings("unchecked") @Override public void setElementsList(ListModel list) {  this.list.setModel(list);  this.list.repaint(); } @Override public......

原文转载:http://www.shaoqun.com/a/892285.html

跨境电商:https://www.ikjzd.com/

折扣网站:https://www.ikjzd.com/w/74

terapeak:https://www.ikjzd.com/w/556

黄远:https://www.ikjzd.com/w/1785


1.意图  用一个中介对象来封装一系列的对象交互。中介者是各个对象不需要显示的相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互  2.动机  面向对象设计鼓励将行为分布到各个对象中。这种分布可能导致对象间有很多连接。在最坏的情况,每一个对象都知道其他对象的存在。  虽然将一个系统分割成许多对象通常可以增强可复用性,但是对象间相互连接的激增又会降低其可复用性。大量的相互连接使得一个对象似
tradekey:https://www.ikjzd.com/w/1630
四川卧龙暴雨引发泥石流 12400名旅客被疏散:http://www.30bags.com/a/424927.html
四川卧龙暴雨致96人被困 当地疏散游客近11000人:http://www.30bags.com/a/425287.html
四川五一旅游景点推荐 :http://www.30bags.com/a/412760.html
四川西南一带迎新轮强降雨 成都广元等地有暴雨:http://www.30bags.com/a/425276.html
囗述我互换丈夫过程 邻居大棒在我体内不停抽搐:http://lady.shaoqun.com/a/246753.html
口述实录:我帮小姨子怀孕的过程:http://lady.shaoqun.com/m/a/79402.html
口述实录:少妇实录:邻居用销魂的床技将我征服:http://lady.shaoqun.com/m/a/251696.html
深圳宝安科技馆8月展览汇总(持续更新):http://www.30bags.com/a/517601.html
2021时尚深圳展蝶讯馆展览好看吗:http://www.30bags.com/a/517602.html
2021时尚深圳蝶讯馆观展攻略:http://www.30bags.com/a/517603.html
深圳欢乐谷夏浪音乐节有朱星杰吗:http://www.30bags.com/a/517604.html

没有评论:

发表评论