设计模式(十五)——中介者模式

mac2024-10-25  52

上一篇:设计模式(十四)——命令模式

下一篇:设计模式(十六)——观察者模式

一、概述

官方解释:Define an object that encapsulates how a set of objects interact.Mediator promotes loose couping by keeping objects from referring to each other explicitly,and it lets you vary their interaction independently.

(用一个中介对象封装一系列的对象交互,中介者使各对象不需要显示的相互作用,从而使其耦合松散,而且可以独立的改变它们之间的交互。)我的理解:将中介引用注入到同事类中,将同事引用注入到中介类中,这样同事类与同事类之间就用中介类连接起来了。

客户端某个具体同事类对象调用自己的operate()方法,该方法中通过注入的中介引用调用中介类的方法,中介类方法中通过注入的同事类引用调用其他同事类的方法,即同事类与同事类之间就用中介类连接起来,中介起到连接各个同事类的作用

colleage.operate() ==> mediator.changed() ==> list中所有colleage.updae()

参与者:中介类(抽象中介类AbstractMediator、具体中介类ConcreteMediator)、同事类(抽象同事类AbstractColleague、具体同事类ConcreteColleague)

类图:

二、代码

代码1——单纯的中介者模式    代码2——中介者模式_软件系统组件例子   代码3——中介者模式_软件系统组件扩展

代码1——单纯的中介者模式:

package mypackage; import java.util.ArrayList; public class DesignPatternDemo { public static void main(String[] args) { Mediator mediator=new ConcreteMediator(); ConcreteColleague colleague=new ConcreteColleague(mediator); mediator.register(colleague); colleague=new ConcreteColleague(mediator); mediator.register(colleague);//注册两个 下面就打印两个 colleague.method2();// } } abstract class Mediator{ protected ArrayList<Colleague> colleagues=new ArrayList<>(); //protected 保证子类可见 ArrayList 保证多个同事 public void register(Colleague colleague){ colleagues.add(colleague); //添加受到该中介影响的同事对象实参(引用形参) } public abstract void operation(); } class ConcreteMediator extends Mediator{ @Override public void operation() { for (int i=0;i<colleagues.size();i++){ colleagues.get(i).method1(); } } } abstract class Colleague{ protected Mediator mediator;// protected 保证子类可见 public Colleague(Mediator mediator){ this.mediator=mediator; } public abstract void method1(); public void method2(){ mediator.operation(); } } class ConcreteColleague extends Colleague{ public ConcreteColleague(Mediator mediator) { super(mediator); } @Override public void method1() { System.out.println("This is a ConcreteColleage"); } }

输出1:

This is a ConcreteColleage This is a ConcreteColleage

代码2——中介者模式_软件系统组件例子:

package mypackage; public class DesignPatternDemo { public static void main(String[] args) { ConcreteMediator mediator = new ConcreteMediator(); Button button = new Button(); TextBox textBox = new TextBox(); Label label = new Label(); button.setMediator(mediator); textBox.setMediator(mediator); label.setMediator(mediator); mediator.button = button; mediator.textBox = textBox; mediator.label = label; button.change(); System.out.println("==============="); label.change(); } } // 四个 Button TextBox Label PictureBox abstract class Mediator { public abstract void componentChanged(Component component); } class ConcreteMediator extends Mediator { public Button button; public TextBox textBox; public Label label; @Override public void componentChanged(Component component) { if (component == button) { System.out.println("This is a button"); textBox.update(); label.update(); } else if (component == textBox) { System.out.println("This is a textBox"); button.update(); label.update(); } else if (component == label) { System.out.println("This is a label"); button.update(); textBox.update(); } else { System.out.println("error"); } } } abstract class Component { protected Mediator mediator;// protected 保证子类可见 public void setMediator(Mediator mediator) { this.mediator = mediator; } public void change() { mediator.componentChanged(this); } public abstract void update(); } class Button extends Component { @Override public void update() { System.out.println("Button update"); } } class TextBox extends Component { @Override public void update() { System.out.println("TextBox update"); } } class Label extends Component { @Override public void update() { System.out.println("Label update"); } }

输出2:

This is a button TextBox update Label update =============== This is a label Button update TextBox update

代码3——中介者模式_软件系统组件扩展:

package mypackage; public class DesignPatternDemo { public static void main(String[] args) { ConcreteMediator mediator=new ConcreteMediator(); Button button=new Button(); TextBox textBox=new TextBox(); Label label=new Label(); PictureBox pictureBox=new PictureBox(); button.setMediator(mediator); textBox.setMediator(mediator); label.setMediator(mediator); pictureBox.setMediator(mediator); mediator.button=button; mediator.textBox=textBox; mediator.label=label; mediator.pictureBox=pictureBox; button.change(); System.out.println("==============="); pictureBox.change(); } } // 四个 Button TextBox Label PictureBox abstract class Mediator{ public abstract void componentChanged(Component component); } class ConcreteMediator extends Mediator{ public Button button; public TextBox textBox; public Label label; public PictureBox pictureBox; @Override public void componentChanged(Component component) { if (component==button) { System.out.println("This is a button"); textBox.update(); label.update(); pictureBox.update(); }else if (component==textBox) { System.out.println("This is a textBox"); button.update(); label.update(); pictureBox.update(); }else if (component==label) { System.out.println("This is a label"); button.update(); textBox.update(); pictureBox.update(); }else if (component==pictureBox) { System.out.println("This is a pictureBox"); button.update(); textBox.update(); label.update(); }else { System.out.println("error"); } } } abstract class Component{ protected Mediator mediator;// protected 保证子类可见 public void setMediator(Mediator mediator){ this.mediator=mediator; } public void change(){ mediator.componentChanged(this); } public abstract void update(); } class Button extends Component{ @Override public void update() { System.out.println("Button update"); } } class TextBox extends Component{ @Override public void update() { System.out.println("TextBox update"); } } class Label extends Component{ @Override public void update() { System.out.println("Label update"); } } class PictureBox extends Component{ @Override public void update() { System.out.println("PictureBox update"); } }

输出3:

This is a button TextBox update Label update PictureBox update =============== This is a pictureBox Button update TextBox update Label update

三、小结

中介者模式中,各个具体同事类的引用注入中介者类中,方便中介者类调用它们的方法,同时,中介引用注入同事类中,方便它们调用中介类方法,通过这种双向注入的方式,一个同事类的operate()方法可以间接调用其他同事类的update()方法,而实现这种间接调用的关键在于中介类。这就是中介者模式。

注意:关于mediator.change()方法中,要不要更新引起该变化的colleage对象的update()方法,这一点不是很重要,根据具体项目开发来,一切为需求服务。

 

附:中介者模式和观察者模式区别

先写结论:在单纯的类图、模式结构上没有本质区别,区别是在项目开发中根据业务需求而造成的区别

明细:两种模式都是行为型设计模式,中介者模式核心类是Mediator,参与者类是Colleage类,观察者模式核心类是Subject,参与者类是Observer。

1、类图、类的结构组成相同:中介者模式  Mediator中注入Colleage类型的list,提供一个change()方法,Colleage类中注入Mediator引用,提供opearate()和update()方法

观察者模式 Subject注入Observer类型的list,提供一个notify()方法,Observer类中注入Subject引用,提供operate()和update()方法

从类图来看,注入包括类中属性注入和方法中形参注入,两种方式没有本质区别,只要可以完成业务逻辑即可,所以其类图类的结构没有本质区别

2、函数调用基本架构相同:中介者模式  colleage.operate() ==> mediator.change() ==> list中所有colleage.update()

观察者模式  observer.opearate() ==> subject.notify() ==> list中所有observer.update()

从函数调用基本架构来看,都是客户端直接调用参与者类的operate(),间接调用其他参与者类的update(),没有本质区别

3、业务逻辑意义不同:一般来说,中介者模式的各个参与类都是不同类对象,像本文的Button Label ComboBox PictureBox,扩展的的时候要新建参与者类;而观察者类参与类是一个类的不同对象,像另一文的Player类,扩展的时候不用新建参与类,只要在客户端新建一个对象就好了

4、业务逻辑——单向与双向不同:一般来说,中介者模式中,基本上都是双向的,每一个Colleage参与类都可以operate()间接调用其他Colleage参与类的update()方法,也可以被其他Colleage类的operate()间接调用,任何时候都是双向的,各个参与者之间是绝对平级的,没有任何上下级关系;

观察者模式中,可以是双向的(你可以观察我的变化,我也可以观察你的变化),也可以是单向的(我可以观察你的变化,你也可以观察我的变化,但是在业务逻辑上你观察我没有意义)(比如老师上课,老师与学生,老师Observer的变化通过Subject被学生Observer观察,但是学生的变化没有必要给老师观察;比如交警指挥,交警与司机,交警Observer的变化通过Subject被司机Observer观察,但是司机的变化没有必要给交警观察);

即:在观察者模式一些情况下,代码上完全可以实现双向观察,但逻辑上没有意义,从而造成了观察者模式中参与者Observer之间特殊与一般的关系.

5、侧重点不同:

观察者模式:不用关心这个列表里有谁,只用关心想让谁加入让谁退出;

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

观察者模式一般提供join()和quit()方法,关心谁加入谁退出,中介者模式一般提供join()就好,也可以提供quit() 。

 

中介者模式:

https://blog.csdn.net/qq_36963950/article/details/102846157

观察者模式:

https://blog.csdn.net/qq_36963950/article/details/102866233

 

 

上一篇:设计模式(十四)——命令模式

下一篇:设计模式(十六)——观察者模式

 

最新回复(0)