鸣谢:《大话设计模式》
简介
是一种行为型设计模式,用于减少对象之间的直接通信,通过引入一个中介者对象来协调和管理对象之间的交互。中介者模式旨在降低对象之间的耦合度,以便更容易维护和扩展系统。
迪米特法则的应用
主要组成部分:
- 中介者(Mediator):中介者是一个接口或抽象类,它定义了对象之间的通信协议。中介者通常包含方法来注册、移除和通知参与者对象。
-
具体中介者(Concrete Mediator):具体中介者是中介者接口的实现,它负责实际协调对象之间的交互。具体中介者通常维护一个对象列表,跟踪和管理参与者对象。
-
参与者(Colleague):参与者是对象之间的通信实体,它们相互通信通过中介者而不是直接通信。参与者对象通常实现一个接口,以便与中介者进行交互。
工作流程
-
参与者对象将消息发送给中介者,而不是直接发送给其他参与者。
-
中介者接收到消息后,决定如何处理该消息,可能会转发给其他参与者。
-
参与者对象根据中介者的指示进行相应的操作。
例子
结构
群消息例子代码
具体中介者(Concrete Mediator)
/**
* @author: lpy
* @Date: 2023/11/04
* @desc: 中介者
*/
public class QQGroup {
public static void sendMsg(User u, String msg){
System.out.println("["+u.getName()+"]:"+msg);
}
}
参与者(Colleague)
/**
* @author: lpy
* @Date: 2023/11/04
*/
@Data
public class User {
private String name;
public User(String name){
this.name = name;
}
public void sendMsg(String msg){
QQGroup.sendMsg(this,msg);
}
}
测试类
/**
* @author: lpy
* @Date: 2023/11/04
*/
public class QQMsgTest {
public static void main(String[] args) {
User jack = new User("jack");
User rose = new User("rose");
jack.sendMsg("hello rose");
rose.sendMsg("hi jack, i change my mind");
}
}
联合国例子代码
中介者(Mediator)
/**
* @author: lpy
* @Date: 2023/11/04
* @desc: 抽象中介者
*/
public abstract class UnitedNations {
public abstract void declare(Country c, String msg);
}
具体中介者(Concrete Mediator)
/**
* @author: lpy
* @Date: 2023/11/04
* @desc: 具体中介者
*/
public class ConcreteUN extends UnitedNations{
private USA usa;
private RSA rsa;
// 联合国安理会了解所有的国家,所以拥有美国俄罗斯等的属性
public void setUsa(USA u){
this.usa = u;
}
public void setRsa(RSA r){
this.rsa = r;
}
@Override
public void declare(Country c, String msg) {
// 重写了声明方法,实现了两个对象间的通信
if (c==this.usa){
this.rsa.getMsg(msg);
}else if (c==this.rsa){
this.usa.getMsg(msg);
}
}
}
参与者(Colleague)
/**
* @author: lpy
* @Date: 2023/11/04
*/
public abstract class Country {
protected UnitedNations un;
public Country(UnitedNations un){
this.un = un;
}
public abstract void getMsg(String msg);
public abstract void declareMsg(String msg);
}
/**
* @author: lpy
* @Date: 2023/11/04
*/
public class USA extends Country{
public USA(UnitedNations un) {
super(un);
}
@Override
public void getMsg(String msg) {
System.out.println("老美获取信息"+msg);
}
@Override
public void declareMsg(String msg) {
un.declare(this,msg);
}
}
/**
* @author: lpy
* @Date: 2023/11/04
*/
public class RSA extends Country{
public RSA(UnitedNations un) {
super(un);
}
@Override
public void getMsg(String msg) {
System.out.println("俄国获取信息"+msg);
}
@Override
public void declareMsg(String msg) {
un.declare(this, msg);
}
}
测试类
/**
* @author: lpy
* @Date: 2023/11/04
*/
public class UnTest {
public static void main(String[] args) {
ConcreteUN concreteUN = new ConcreteUN();
RSA rsa = new RSA(concreteUN);
USA usa = new USA(concreteUN);
concreteUN.setRsa(rsa);
concreteUN.setUsa(usa);
usa.declareMsg(":美国国家原子能研究中心人员名单");
rsa.declareMsg(":俄罗斯太空部署战略");
}
}
应用
常用于聊天室、飞机控制系统、交通信号灯控制、图形用户界面(GUI)框架等场景,以协调和管理多个对象之间的交互。这有助于改善系统的可维护性和可扩展性。
中介者模式优缺点
- 优点:
- 降低耦合:中介者模式降低了对象之间的直接耦合度,使对象更加独立,从而提高了系统的可维护性。
-
集中控制:中介者可以集中控制对象之间的交互,使系统更易于管理和维护。
-
复杂交互:中介者模式适用于具有复杂交互和依赖关系的系统,有助于简化对象之间的通信。
-
支持松散耦合:通过引入中介者,支持了对象之间的松散耦合,从而使系统更容易扩展和修改。
-
缺点:
- 复杂性增加:引入中介者对象可能会增加系统的复杂性,特别是在系统变得复杂并且有大量参与者时。中介者本身需要管理和协调多个对象之间的交互,这可能导致中介者变得复杂和难以维护。
-
单点故障:中介者成为了系统的单一点,如果中介者出现问题或失败,整个系统的交互将受到影响。这种单点故障可能导致系统不稳定。
-
通信延迟:由于所有对象的通信都经过中介者,可能会引入额外的通信延迟。这在需要高性能和实时性的系统中可能成为问题。
-
限制了直接通信:中介者模式的设计目标是降低对象之间的直接耦合,但这也意味着对象之间不能直接通信。在某些情况下,对象之间的直接通信可能更高效。
-
复杂的维护:当系统中的对象和交互关系发生变化时,维护中介者模式可能变得复杂。在修改中介者或增加新参与者时,需要小心确保不破坏系统的稳定性。
7 大设计原则
不能全部遵守 , 也不能不遵守 , 注意平衡 功能 和 系统复杂度 , 找到最合适的一个点 ;
- 单一职责原则(Single Responsibility Principle - SRP):
这个原则规定一个类应该只有一个改变的理由,也就是说,一个类应该只有一个单一的职责。这有助于保持类的简单性和可维护性,因为每个类只需关注一个特定的功能。
- 开放-封闭原则(Open-Closed Principle - OCP):
开放-封闭原则要求系统中的软件实体(类、模块、函数等)应该对扩展开放,对修改封闭。这意味着当需要添加新功能时,应该通过扩展现有代码来实现,而不是修改原有代码。
- 里氏替换原则(Liskov Substitution Principle - LSP):
里氏替换原则规定,子类应该能够替换其父类,而不会影响程序的正确性。也就是说,子类应该继承父类的行为,但可以扩展或修改该行为,但不应该改变父类的行为。
- 接口隔离原则(Interface Segregation Principle - ISP):
接口隔离原则要求一个类不应该强迫其客户端依赖于它们不需要的接口。应该根据客户端的需求定义小而精确的接口,而不是大而笨重的接口。
- 依赖倒置原则(Dependency Inversion Principle - DIP):
依赖倒置原则要求高级模块不应该依赖于低级模块,它们都应该依赖于抽象。具体来说,这意味着应该通过抽象接口或抽象类来定义模块之间的依赖关系,而不是直接依赖于具体实现。
- 迪米特法则(Law of Demeter - LoD):
如果两个类不必彼此直接通信,那么这两个类就不应当发生直接的相互作用。如果其中一个类需要调用另一个类的某一个方法的话,可以通过第三者转发这个调用。
- 合成复用原则(Composite Reuse Principle - CRP):
合成复用原则鼓励通过组合(合成)已有的类来实现新功能,而不是通过继承现有的类。这样可以降低系统的耦合度,并且更加灵活。
源码位置
全部源码github.com/xs-alpha/designPattern
参考文献
- 《大话设计模式》
-
慕课视频《Java设计模式精讲 Debug方式+内存分析》
如有内容侵权,麻烦联系博主删除