场景
场景1:
(1)三个模块
(2)模块1调用模块2和模块3;模块2要调用模块1和模块3;模块3要调用模块1和模块2
场景2:
(1)电商系统:订单、库存、调度中心之间交互,使用中介者模式做成完全解耦。
内容
- 中介者模式(Mediator Pattern)是用来降低多个对象和类之间的通信复杂性。这种模式提供了一个中介类,该类通常处理不同类之间的通信,并支持松耦合,使代码易于维护。中介者模式属于行为型模式。
- 用一个中介对象来封装一系列的对象交互,中介者使各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互。
1. 不使用设计模式
1.1 类图
1.2 代码
-
每个模块提供一个供别人调用的方法:
excute(String invoker)
- 真正代码耦合调用逻辑在:excute里面
public class NonPattern2 {
public static void main(String[] args) {
Module1 module1 = new Module1();
Module2 module2 = new Module2();
Module3 module3 = new Module3();
module1.excute();
module2.excute();
module3.excute();
/**
* 输出:
* 模块1在调用模块2功能
* 模块1在调用模块3功能
* 模块2在调用模块1功能
* 模块2在调用模块3功能
* 模块3在调用模块1功能
* 模块3在调用模块2功能
*/
}
public static class Module1{
public void excute(){
//模块1调用模块2 和 模块3
Module2 module2 = new Module2();
Module3 module3 = new Module3();
module2.excute("模块1");
module3.excute("模块1");
}
public void excute(String invoker){//执行者
System.out.println(invoker+"在调用模块1功能");
}
}
public static class Module2{
public void excute(){
//模块2 调用模块1 和 模块3
Module1 module1 = new Module1();
Module3 module3 = new Module3();
module1.excute("模块2");
module3.excute("模块2");
}
public void excute(String invoker){//执行者
System.out.println(invoker+"在调用模块2功能");
}
}
public static class Module3{
public void excute(){
//模块3 调用模块1 和 模块2
Module1 module1 = new Module1();
Module2 module2 = new Module2();
module1.excute("模块3");
module2.excute("模块3");
}
public void excute(String invoker){//执行者
System.out.println(invoker+"在调用模块3功能");
}
}
}
2. 中介者模式
2.1 类图
- 模块和中介者互相依赖。
- 为了实现模块之间调用解耦,把模块的调用书写在Mediator,然后调用行为传参给各个模块,然后执行调用,相当于把调用当成一个组件分离出去,需要调用的时候,直接传递此组件。
- 每个模块提供一个供其他模块调用的方法
- 因为最后触发调用的是各个模块主动触发,所以我们需要在各个模块书写:excute方法
2.2 代码
public class MediatorPattern2 {
public static void main(String[] args) {
//1.创建中介者
Mediator mediator = new Mediator();
//2.创建个模块并且给创建的中介者赋值
Module1 module1 = new Module1(mediator);
Module2 module2 = new Module2(mediator);
Module3 module3 = new Module3(mediator);
//3.输出调用
module1.excute();
module2.excute();
module3.excute();
/**
* 输出:
* 模块1通知中介者 : 在调用模块2功能
* 模块1通知中介者 : 在调用模块2功能
* 模块2通知中介者 : 在调用模块1功能
* 模块2通知中介者 : 在调用模块2功能
* 模块3通知中介者 : 在调用模块1功能
* 模块3通知中介者 : 在调用模块2功能
*/
}
//=======================中介者========================
public static class Mediator{
private Module1 module1;
private Module2 module2;
private Module3 module3;
public void module1Invoke(){
module2.excute("模块1通知中介者 ");
module3.excute("模块1通知中介者 ");
}
public void module2Invoke(){
module1.excute("模块2通知中介者 ");
module3.excute("模块2通知中介者 ");
}
public void module3Invoke(){
module1.excute("模块3通知中介者 ");
module3.excute("模块3通知中介者 ");
}
public Module1 getModule1() {
return module1;
}
public void setModule1(Module1 module1) {
this.module1 = module1;
}
public Module2 getModule2() {
return module2;
}
public void setModule2(Module2 module2) {
this.module2 = module2;
}
public Module3 getModule3() {
return module3;
}
public void setModule3(Module3 module3) {
this.module3 = module3;
}
}
public static class Module1{
private Mediator mediator;
public Module1(Mediator mediator){
this.mediator = mediator;
this.mediator.setModule1(this);
}
public void excute(){
mediator.module1Invoke();
}
public void excute(String invoker){
System.out.println(invoker+": 在调用模块1功能");
}
}
public static class Module2{
private Mediator mediator;
public Module2(Mediator mediator){
this.mediator = mediator;
this.mediator.setModule2(this);
}
public void excute(){
mediator.module2Invoke();
}
public void excute(String invoker){
System.out.println(invoker+": 在调用模块2功能");
}
}
public static class Module3{
private Mediator mediator;
public Module3(Mediator mediator){
this.mediator = mediator;
this.mediator.setModule3(this);
}
public void excute(){
mediator.module3Invoke();
}
public void excute(String invoker){
System.out.println(invoker+": 在调用模块2功能");
}
}
}
3.总结
3.1 不使用设计模式对比
- 模块之间有非常复杂的互相之间的跟蜘蛛网一样的调用;每个模块都要去care很多其他的模块,互相之间耦合很严重
- 后面在修改代码的时候,代码不好改,模块2一旦修改了自己的代码,可能会影响模块1和模块3
3.2 使用原型模式
优点:
- module1,只要知道一个中介者就可以了,具体跟其他模块的交互都封装在中介者里面了。
- module2,只要知道一个中介者就可以了,具体跟其他模块的交互都封装在中介者里面了。
- module3,只要知道一个中介者就可以了,具体跟其他模块的交互都封装在中介者里面了。
- module1、2、3之间不再有任何的耦合,不再有复杂的交互关系,互相之间修改不会对对方产生什么影响。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。