设计模式之调停者 Mediator

简介: 设计模式之调停者 Mediator

核心思想:通过引入一个中介对象来降低对象之间的直接交互。在该模式中,调停者对象充当了所有相关对象之间的协调者,其主要作用是接收并处理这些对象发出的请求。通过使用调停者模式,可以减少对象之间的依赖性,从而提高系统的可维护性和可扩展性

场景:假设在一个游戏中,现在有A、B、C三名玩家,有一名玩家释放技能,其他两名玩家就会减少HP2点,那么这个时候如果按照传统的设计,A、B、C之间就需要相互耦合,这显然就违背了迪米特原则,因此就有了调停者模式。将释放技能这个操作交给调停者来做,调停者持有A、B、C三个对象

调停者模式的必备要素:

  • 抽象调停者: 定义了同事类与调停者交互的接口,其中主要方法是一个事件方法。
  • 具体调停者: 实现了抽象调停者定义的事件方法,同时具体调停者知道所有具体的同事类,并且负责协调各同事类之间的交互。
  • 抽象同事类:定义了调停者和同事类的交互接口,同事对象只知道调停者,而不知道其他的同事对象。
  • 具体同事类:具体同事类都是继承自抽象同事类。实现自己的业务,然后当要与其他同事类进行通信的时候,就与持有的调停者进行通信,调停者负责与其他同事类进行交互。

下面我们看一下具体的代码实现:

首先,创建一个抽象的同事类,需要持有调停者类,并提供方法来操作对象的属性

public abstract class AbstractHero {
    protected AbstractMediator mediator;
    protected int HP;
    public AbstractHero(AbstractMediator mediator) {
        HP = 0;
        this.mediator = mediator;
    }
    abstract void printHP();
    public void addHP(int i) {
        this.HP += i;
    }
    public void subtractHP(int i) {
        this.HP -= i;
    }
}

然后我们定义抽象的调停者类,提供操作方法即可

public abstract class AbstractMediator {
    abstract void useSkill(AbstractHero hero);
}

具体的同事类:

public class A extends AbstractHero{
    public A(AbstractMediator mediator) {
        super(mediator);
    }
    @Override
    void printHP() {
        System.out.println(this.HP);
    }
}
public class B extends AbstractHero{
    public B(AbstractMediator mediator) {
        super(mediator);
    }
    @Override
    void printHP() {
        System.out.println(this.HP);
    }
}
public class C extends AbstractHero{
    public C(AbstractMediator mediator) {
        super(mediator);
    }
    @Override
    void printHP() {
        System.out.println(this.HP);
    }
}

最后定义具体的调停者类,需要持有所有的同事类的对象

public class GameMediator extends AbstractMediator{
    private static final GameMediator GAME_MEDIATOR = new GameMediator();
    private GameMediator(){}
    private A a;
    private B b;
    private C c;
    public static GameMediator getGameMediator(){
        return GAME_MEDIATOR;
    }
    @Override
    void useSkill(AbstractHero hero) {
        if (hero instanceof A){
            System.out.println("A发动技能:A回复两点HP,B、C扣除两点HP");
            a.addHP(2);
            b.subtractHP(2);
            c.subtractHP(2);
        }else if (hero instanceof B){
            System.out.println("B发动技能:B回复两点HP,A、C扣除两点HP");
            b.addHP(2);
            a.subtractHP(2);
            c.subtractHP(2);
        }else if (hero instanceof C){
            System.out.println("C发动技能:C回复两点HP,A、B扣除两点HP");
            c.addHP(2);
            b.subtractHP(2);
            a.subtractHP(2);
        }
    }
    public void setA(A a) {
        this.a = a;
    }
    public void setB(B b) {
        this.b = b;
    }
    public void setC(C c) {
        this.c = c;
    }
}

测试:

public static void main(String[] args) {
        GameMediator gameMediator = GameMediator.getGameMediator();
        A a = new A(gameMediator);
        gameMediator.setA(a);
        B b = new B(gameMediator);
        gameMediator.setB(b);
        C c = new C(gameMediator);
        gameMediator.setC(c);
        gameMediator.useSkill(a);
        a.printHP();
        b.printHP();
        c.printHP();
        gameMediator.useSkill(b);
        a.printHP();
        b.printHP();
        c.printHP();
    }

可以看到在上面的例子之中,我们将A、B、C三个对象全部交给调停者来管理,由他来控制发动技能这个过程,这样就避免了对象之间的相互耦合,但是缺点是调停者本身的代码会比较冗余。大量的if else判断可以考虑使用策略模式来优化。

目录
相关文章
|
存储 数据采集 数据挖掘
开源的Python科学计算库:NumPy
开源的Python科学计算库:NumPy
833 1
开源的Python科学计算库:NumPy
|
人工智能 自然语言处理
使用Kimi+Markmap总结文件内容生成思维导图原创
一份文件内容太长,完整阅读下来太费时间,但如果使用AI进行内容提炼,再总结成思维导图,方便快速看到这份文件的核心内容和主题结构,就会极大地节约时间,目前就可以使用Kimi+Markmap这两个工具,帮我们把ppt、word、pdf等文件内容快速总结成思维导图。
3008 8
使用Kimi+Markmap总结文件内容生成思维导图原创
|
机器学习/深度学习 监控 算法
Keras进阶:模型调优与部署
该文介绍了Keras模型调优与部署的策略。调优包括调整网络结构(增减层数、改变层类型、使用正则化)、优化算法与参数(选择优化器、学习率衰减)、数据增强(图像变换、噪声添加)、模型集成(Bagging、Boosting)和超参数搜索(网格搜索、随机搜索、贝叶斯优化)。部署涉及模型保存加载、压缩(剪枝、量化、蒸馏)、转换(TensorFlow Lite、ONNX)和服务化(TensorFlow Serving、Docker)。文章强调了持续监控与更新的重要性,以适应不断变化的数据和需求。【6月更文挑战第7天】
558 8
|
JavaScript 定位技术
RPG游戏开发基础教程
RPG游戏开发基础教程 第一步 下载RPG Maker 开发工具包 1.RPG Maker 是什么? RPG Maker 是由Enterbrain公司推出的RPG制作工具。 中文译名为RPG制作大师。
2833 0
|
JavaScript
vue element plus Radio 单选框
vue element plus Radio 单选框
700 0
伪随机序列——m序列及MATLAB仿真
伪随机序列——m序列及MATLAB仿真
1955 2
|
数据可视化 算法 数据挖掘
数据分享|R语言IMDb TOP250电影特征数据挖掘可视化分析受众偏好、排名、投票、评分(上)
数据分享|R语言IMDb TOP250电影特征数据挖掘可视化分析受众偏好、排名、投票、评分
|
人工智能 并行计算 PyTorch
【AI 大模型】离线运行ChatGLM2-6B(清华大模型)
【AI 大模型】离线运行ChatGLM2-6B(清华大模型)
2598 0
|
Arthas Prometheus 监控
使用JDK自带工具调优JVM的常用命令
使用JDK自带工具调优JVM的常用命令
333 0
|
算法 机器人 API
【ROS】TF2坐标转换及实战示例
ROS中提供了坐标转换的软件包 Transform Frame TF的作用是ROS中实现不同坐标点/向量的转换。
1308 0

热门文章

最新文章

下一篇
开通oss服务