1.1概述
用一个中介对象来封装一系列的对象交互。中介者使各对象不需要显示地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互。这就是中介者模式的定义。
一个对象含有另一个对象的引用是面向对象中经常使用的方式,也是面向对象所提倡的,即少用继承多用组合。但是怎样合理地组合对象对系统今后的扩展、维护和对象的复用是至关重要的,这也正是学习设计模式的重要原因。
例如,在一个房屋租赁系统中,有很多对象,有些对象是求租者,有些是出租者,如果要求他们之间必须成为朋友才能进行有关租赁的操作,显然不利于系统的维护和发展,因此,每当有新的出租者或求租者加入该系统,这个新的加入者必须和现有系统中的所有人互为朋友后才能和他们进行有关租赁的操作,这就意味着要修改大量的代码,这对系统的维护是非常不利的也是无法容忍的。一个好的解决办法就是在房屋租赁系统中建立一个称作中介者的对象,中介者包含系统中所有其他对象的引用,而系统中的其他对象只包含中介者的引用,也就是说中介者和大家互为朋友、中介者使系统中的其他对象完全解耦,当系统中某个对象需要和系统中另外一个对象交互时,只需将自己的请求通知中介者即可,如果有新的加入者,该加入者只需含有中介者的引用,并让中介者含有自己的引用,他就可以和系统中其他对象进行有关租赁操作,具体如下图一所示:
图一:中介者、出租者和求租者
中介者模式是封装一系列的对象交互的成熟模式,其关键是将对象之间的交互封装在称作中介者的对象中,中介者使各对象不需要显示地相互吸引,这些对象只包含中介者的引用。当系统中某个对象需要和系统中另外一个对象交互时,只需要将自己的请求通知给中介者即可。
1.2模式的结构
中介者模式的结构包含四种角色:
(1)中介者(Mediator):中介者是一个接口,该接口定义了用于同事对象之间进行通信的方法。
(2)具体中介者(ConcreteMediator):具体中介者是实现中介者接口的类。具体中介者需要包含所有具体同事的引用,并通过实现中介者接口中的方法来满足具体同事之间的通信请求。
(3)同事(Colleague):一个接口,规定了具体同事需要实现的方法。
(4)具体同事(ConcreteColleague):实现同事接口的类。具体同事需要包含具体中介者的引用,一个具体同事需要和其他具体同事交互时,只需要将自己的请求通知给它所包含的具体中介者即可。
中介者模式结构的类图如下图二所示:
图二:中介者模式类图
1.3中介者模式的优点
(1)可以避免许多的对象为了通信而相互显示引用,否则,不仅系统难于维护,而且也使其他系统难以复用这些对象。
(2)可以通过中介者将原本分布于多个对象之间的交互行为集中在一起。当这些对象之间需要改变之间的通信行为时,只需要使用一个具体中介者即可,不必修改各个具体同事的代码,即这些同事可被重用。
(3)具体中介者使得各个具体同事完全解耦,修改任何一个具体同事的代码不会影响到其他同事。
(4)具体中介者集中了同事之间是如何交互的细节,使系统比较清楚地知道整个系统中的同事是如何交互的。
(5)当一些对象相互通信,但又无法相互包含对方的引用,那么使用中介者模式就可以使这些对象相互通信。
1.4适合使用中介者模式的情景
(1)许多对象以复杂的方式交互,所导致的依赖关系使系统难以理解和维护。
(2)一个对象引用其他很多对象,导致难以复用该对象。
1.5中介者模式的使用
以下通过一个简单的问题来描述中介者模式中所涉及的各个角色。
古代相互交战的A、B、C三方,想通过一个中介者调停之间的战火。A方委托调停者转达的信息是:“要求B方归还曾抢夺的100斤土豆,要求C方归还曾抢夺的20头牛”;B方委托调停者转达的信息是:“要求A方归还曾抢夺的10只公鸡,要求C方归还曾抢夺的15匹马”;C方委托调停者转达的信息是:“要求A方曾抢夺的360斤小麦,要求B方曾抢夺的50头驴”。
针对上述问题,使用中介者模式设计若干个类。具体如下:
首先看一下本实例构建框架具体类和1.2模式的结构中类图的对应关系,如下图所示:
(1)同事(Colleague)
本问题中,同事接口是Colleague,定义了具体同事,即交战各方需要实现的方法。Colleague接口的代码如下:
package com.liuzhen.nine_mediator; public interface Colleague { public void giveMess(String[] mess); public void receiverMess(String mess); public void setName(String name); public String getName(); }
(2)具体中介者(Mediator)
本问题中,只需要一个具体中介者,并不需要一个中介者接口,具体中介者是ConcreteMediator类,代码如下:
package com.liuzhen.nine_mediator; public class ConcreteMediator { ColleagueA colleagueA; ColleagueB colleagueB; ColleagueC colleagueC; public void registerColleagueA(ColleagueA colleagueA){ this.colleagueA = colleagueA; } public void registerColleagueB(ColleagueB colleagueB){ this.colleagueB = colleagueB; } public void registerColleagueC(ColleagueC colleagueC){ this.colleagueC = colleagueC; } public void deliveMess(Colleague colleague , String[] mess){ if(colleague == colleagueA){ if(mess.length >= 2){ colleagueB.receiverMess(colleague.getName()+mess[0]); colleagueC.receiverMess(colleague.getName()+mess[1]); } } if(colleague == colleagueB){ if(mess.length >= 2){ colleagueA.receiverMess(colleague.getName()+mess[0]); colleagueC.receiverMess(colleague.getName()+mess[1]); } } if(colleague == colleagueC){ if(mess.length >= 2){ colleagueA.receiverMess(colleague.getName()+mess[0]); colleagueB.receiverMess(colleague.getName()+mess[1]); } } } }
(3)具体同事(ConcreteColleague)
对于本问题。有ColleagueA、ColleagueB和ColleagueC三个具体同事,其实例分别表示交战的三方,代码如下:
ColleagueA.java
package com.liuzhen.nine_mediator; public class ColleagueA implements Colleague { ConcreteMediator mediator; //中介者 String name; ColleagueA(ConcreteMediator mediator){ this.mediator = mediator; mediator.registerColleagueA(this); } public void giveMess(String[] mess) { // TODO Auto-generated method stub mediator.deliveMess(this, mess); } public void receiverMess(String mess) { // TODO Auto-generated method stub System.out.println(name+"收到的消息:"); System.out.println("\t"+mess); } public void setName(String name) { // TODO Auto-generated method stub this.name = name; } public String getName() { // TODO Auto-generated method stub return name; } }
ColleagueB.java
package com.liuzhen.nine_mediator; public class ColleagueB implements Colleague { ConcreteMediator mediator; //中介者 String name; ColleagueB(ConcreteMediator mediator){ this.mediator = mediator; mediator.registerColleagueB(this); } public void giveMess(String[] mess) { // TODO Auto-generated method stub mediator.deliveMess(this, mess); } public void receiverMess(String mess) { // TODO Auto-generated method stub System.out.println(name+"收到的消息:"); System.out.println("\t"+mess); } public void setName(String name) { // TODO Auto-generated method stub this.name = name; } public String getName() { // TODO Auto-generated method stub return name; } }
ColleagueC.java
package com.liuzhen.nine_mediator; public class ColleagueC implements Colleague { ConcreteMediator mediator; //中介者 String name; ColleagueC(ConcreteMediator mediator){ this.mediator = mediator; mediator.registerColleagueC(this); } public void giveMess(String[] mess) { // TODO Auto-generated method stub mediator.deliveMess(this, mess); } public void receiverMess(String mess) { // TODO Auto-generated method stub System.out.println(name+"收到的消息:"); System.out.println("\t"+mess); } public void setName(String name) { // TODO Auto-generated method stub this.name = name; } public String getName() { // TODO Auto-generated method stub return name; } }
(4)具体使用
通过NineApplication类来具体实现上述相关类和接口,来实现适配器模式的运用,其代码如下:
package com.liuzhen.nine_mediator; public class NineApplication { public static void main(String[] args){ ConcreteMediator mediator = new ConcreteMediator(); ColleagueA colleagueA = new ColleagueA(mediator); ColleagueB colleagueB = new ColleagueB(mediator); ColleagueC colleagueC = new ColleagueC(mediator); colleagueA.setName("A国"); colleagueB.setName("B国"); colleagueC.setName("C国"); String[] messA = {"要求B方归还曾抢夺的100斤土豆" , "要求C方归还曾抢夺的20头牛"}; colleagueA.giveMess(messA); String[] messB = {"要求A方归还曾抢夺的10只公鸡" , "要求C方归还曾抢夺的15匹马"}; colleagueB.giveMess(messB); String[] messC = {"要求A方曾抢夺的360斤小麦" , "要求B方曾抢夺的50头驴"}; colleagueC.giveMess(messC); } }
运行结果:
B国收到的消息:
A国要求B方归还曾抢夺的100斤土豆
C国收到的消息:
A国要求C方归还曾抢夺的20头牛
A国收到的消息:
B国要求A方归还曾抢夺的10只公鸡
C国收到的消息:
B国要求C方归还曾抢夺的15匹马
A国收到的消息:
C国要求A方曾抢夺的360斤小麦
B国收到的消息:
C国要求B方曾抢夺的50头驴
相关推荐
《设计模式学习笔记》主要探讨了GOF的23种设计模式以及类设计的基本原则,旨在帮助开发者理解和应用这些经过时间验证的成熟解决方案。设计模式是面向对象软件设计中的核心概念,它们为解决常见的设计问题提供了标准...
这个“23种设计模式学习笔记”文档将引导你深入理解这些模式,并帮助你在实际编程中有效地应用它们。以下是对23种设计模式的详细解读: 1. **单例模式**:确保一个类只有一个实例,并提供全局访问点。它常用于控制...
行为型模式:模版方法模式、命令模式、访问者模式、迭代器模式、观察者模式、中介者模式、备忘录模式、解释器模式(Interpreter模式)、状态模式、策略模式、职责链模式(责任链模式) 2) 学习目标:通过学习,学员...
设计模式的学习不仅帮助我们编写更可维护、可扩展的代码,还能提高团队间的沟通效率,因为它们提供了通用的语言和解决方案。在实际开发中,灵活运用这些设计模式可以有效解决设计问题,提升代码质量。因此,深入理解...
"GoF 23种设计模式学习笔记" 是一个深入探讨这23个经典设计模式的资源,这些模式最初由Erich Gamma、Richard Helm、Ralph Johnson和John Vlissides四位作者在1994年的著作《设计模式:可复用面向对象软件的基础》中...
以下是一些在尚学堂300Java设计模式部分学习笔记中涉及的设计模式的知识点: 创建型模式: 创建型模式主要解决对象创建的问题,确保系统的灵活性和封装创建细节。学习笔记中提到了5种创建型模式: 1. 单例模式...
### 设计模式学习笔记 #### 引言 设计模式(Design Patterns)是在软件设计领域内广泛应用的一种实践指南,它提供了一系列解决常见问题的方案。设计模式可以被理解为面向对象软件设计的经验总结,是对特定面向对象...
### 23种设计模式学习笔记 #### 一、软件设计模式的概念与意义 **概念:** 软件设计模式(Software Design Pattern),又称设计模式,是一套被广泛采用、经过整理和分类的代码设计经验总结。它针对软件设计过程中...
笔记文件的名称“DesignPatternStudy-master”暗示了这是一份专注于设计模式学习的系列笔记,而"master"可能表明这是该系列的核心或主文件,其他相关的文件可能是补充材料或者分章节的学习笔记。
为了更有效地学习设计模式,除了理论学习之外,还应通过实践去应用这些模式。这通常意味着在项目中尝试使用不同的设计模式去解决实际遇到的问题,并不断反思和评估这些模式的适用性。实践中,可以通过重构现有代码,...
《设计模式:可复用面向对象软件的基础》一书介绍了23种经典的设计模式,这些模式大致可以分为三大类: 1. **创建型模式**:专注于对象的创建机制,确保系统在合适的时机创建正确的对象。 - **单例模式**...
本笔记和代码集合涵盖了多种重要的设计模式,旨在帮助开发者编写更可维护、可扩展和可重用的JavaScript代码。 1. **工厂模式**:这是一种创建型设计模式,它提供了一个创建对象的接口,但允许子类决定实例化哪一个...
而这份笔记则是将书中的概念转化为Java语言的实例,提供了学习设计模式的实战应用。 首先,设计模式可以大致分为三大类:创建型模式、结构型模式和行为型模式。创建型模式涉及对象的创建机制,结构型模式关注的是类...
在《23个设计模式图解--学习笔记》中,我们探讨了这些模式,以便于理解和应用到实际开发中。以下是这23个设计模式的详细说明: 1. **工厂方法**(Factory Method):定义一个用于创建对象的接口,让子类决定实例化...
设计模式是软件工程中的一种重要概念,它代表了在特定情境下解决常见问题的最佳实践。...通过“23种设计模式的解析与C++实现.pdf”和“Source”文件,读者可以深入学习并实践这些模式,提升自己的编程技能。
- 中介者模式:用一个中介对象来封装一系列的对象交互。 - 备忘录模式:在不破坏封装的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。 - 状态模式:允许一个对象在其内部状态改变时改变它的行为。 -...
### 设计模式笔记 #### 一、引言 设计模式是一种在特定情境下解决软件设计问题的标准化解决方案。它是从无数编程实践中提炼出来的精华,帮助开发者更好地理解和应对复杂的问题。在学习设计模式的过程中,我们通常...
通过阅读这份笔记,读者不仅可以学习到设计模式的基本概念,还能了解到如何在Java环境中实际运用这些模式,提升编程技能。设计模式的学习和掌握是成为一名优秀程序员的必经之路,它们能帮助我们写出更高效、更灵活、...
笔记参考的链接可能指向了一个在线知识库或者文档,提供了丰富的资源和讨论,帮助学习者更好地掌握设计模式。 从压缩包中的文件名称"DesignPattern-main"可以推断,这可能是一个包含源代码的主目录。这个目录中可能...