【Java设计模式】中介者模式

【Java设计模式】中介者模式

一、概述

中介者设计模式旨在减少系统中多个对象或类之间通信的复杂性。它通过提供一个集中的中介者类来处理不同类之间的交互,从而减少它们之间的直接依赖。

二、详细解释及实际示例

  1. 实际示例
    • 想象一个繁忙机场的空中交通管制系统,其中空中交通管制员充当中介者。在这种情况下,许多飞机希望起飞、降落或在机场空域内导航。如果每个飞行员都直接与其他每个飞行员通信,可能会导致混乱和潜在的事故,而不是这样,所有通信都通过空中交通管制员进行。管制员接收请求,处理它们,并向每个飞行员给出清晰、有序的指令。这个集中式系统降低了通信的复杂性,确保了管理机场运营的安全性和效率。这类似于软件中的中介者设计模式,其中一个中央中介者类处理和协调不同对象或系统之间的交互。
  2. 通俗解释
    • 中介者通过强制一组类的通信流经一个中介对象来解耦它们。
  3. 维基百科解释
    • 在软件工程中,中介者模式定义了一个对象,该对象封装了一组对象的交互方式。由于它可以改变程序的运行行为,因此该模式被认为是一种行为模式。在面向对象编程中,程序通常由许多类组成。业务逻辑和计算分布在这些类中。然而,随着更多的类被添加到程序中,特别是在维护和/或重构期间,这些类之间的通信问题可能会变得更加复杂。这使得程序更难阅读和维护。此外,由于任何更改都可能影响其他几个类中的代码,因此更改程序可能会变得困难。使用中介者模式,对象之间的通信被封装在一个中介者对象中。对象不再直接相互通信,而是通过中介者进行通信。这减少了通信对象之间的依赖关系,从而减少了耦合。

三、Java中中介者模式的编程示例

在这个示例中,中介者封装了一组对象的交互方式。它们不是直接相互引用,而是使用中介者接口。
派对成员RogueWizardHobbitHunter都继承自PartyMemberBase并实现PartyMember接口。

public interface PartyMember {
    void joinedParty(Party party);
    void partyAction(Action action);
    void act(Action action);
}
@Slf4j
public abstract class PartyMemberBase implements PartyMember {
    protected Party party;
    @Override
    public void joinedParty(Party party) {
        LOGGER.info("{} joins the party", this);
        this.party = party;
    }
    @Override
    public void partyAction(Action action) {
        LOGGER.info("{} {}", this, action.getDescription());
    }
    @Override
    public void act(Action action) {
        if (party!= null) {
            LOGGER.info("{} {}", this, action);
            party.act(this, action);
        }
    }
    @Override
    public abstract String toString();
}
public class Rogue extends PartyMemberBase {
    @Override
    public String toString() {
        return "Rogue";
    }
}
// Wizard、Hobbit和Hunter的实现类似

我们的中介者系统由Party接口及其实现组成。

public interface Party {
    void addMember(PartyMember member);
    void act(PartyMember actor, Action action);
}
public class PartyImpl implements Party {
    private final List<PartyMember> members;
    public PartyImpl() {
        members = new ArrayList<>();
    }
    @Override
    public void act(PartyMember actor, Action action) {
        for (var member : members) {
            if (!member.equals(actor)) {
                member.partyAction(action);
            }
        }
    }
    @Override
    public void addMember(PartyMember member) {
        members.add(member);
        member.joinedParty(this);
    }
}

这里是一个展示中介者模式实际应用的演示。

public static void main(String[] args) {
    // 创建派对和成员
    Party party = new PartyImpl();
    var hobbit = new Hobbit();
    var wizard = new Wizard();
    var rogue = new Rogue();
    var hunter = new Hunter();
    // 添加派对成员
    party.addMember(hobbit);
    party.addMember(wizard);
    party.addMember(rogue);
    party.addMember(hunter);
    // 执行动作 -> 其他派对成员
    // 会被派对通知
    hobbit.act(Action.ENEMY);
    wizard.act(Action.TALE);
    rogue.act(Action.GOLD);
    hunter.act(Action.HUNT);
}

运行示例的控制台输出如下。

14:05:15.081 [main] INFO com.iluwatar.mediator.PartyMemberBase -- Hobbit joins the party
14:05:15.083 [main] INFO com.iluwatar.mediator.PartyMemberBase -- Wizard joins the party
14:05:15.083 [main] INFO com.iluwatar.mediator.PartyMemberBase -- Rogue joins the party
14:05:15.083 [main] INFO com.iluwatar.mediator.PartyMemberBase -- Hunter joins the party
14:05:15.083 [main] INFO com.iluwatar.mediator.PartyMemberBase -- Hobbit spotted enemies
14:05:15.083 [main] INFO com.iluwatar.mediator.PartyMemberBase -- Wizard runs for cover
14:05:15.083 [main] INFO com.iluwatar.mediator.PartyMemberBase -- Rogue runs for cover
14:05:15.083 [main] INFO com.iluwatar.mediator.PartyMemberBase -- Hunter runs for cover
14:05:15.083 [main] INFO com.iluwatar.mediator.PartyMemberBase -- Wizard tells a tale
14:05:15.083 [main] INFO com.iluwatar.mediator.PartyMemberBase -- Hobbit comes to listen
14:05:15.083 [main] INFO com.iluwatar.mediator.PartyMemberBase -- Rogue comes to listen
14:05:15.083 [main] INFO com.iluwatar.mediator.PartyMemberBase -- Hunter comes to listen
14:05:15.083 [main] INFO com.iluwatar.mediator.PartyMemberBase -- Rogue found gold
14:05:15.083 [main] INFO com.iluwatar.mediator.PartyMemberBase -- Hobbit takes his share of the gold
14:05:15.083 [main] INFO com.iluwatar.mediator.PartyMemberBase -- Wizard takes his share of the gold
14:05:15.083 [main] INFO com.iluwatar.mediator.PartyMemberBase -- Hunter takes his share of the gold
14:05:15.083 [main] INFO com.iluwatar.mediator.PartyMemberBase -- Hunter hunted a rabbit
14:05:15.083 [main] INFO com.iluwatar.mediator.PartyMemberBase -- Hobbit arrives for dinner
14:05:15.083 [main] INFO com.iluwatar.mediator.PartyMemberBase -- Wizard arrives for dinner
14:05:15.083 [main] INFO com.iluwatar.mediator.PartyMemberBase -- Rogue arrives for dinner

四、中介者模式的详细解释及实际示例

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

五、何时在Java中使用中介者模式

当以下情况时使用中介者模式:

  1. 一组对象以定义良好但复杂的方式进行通信。由此产生的相互依赖关系是无结构的,难以理解。
  2. 由于对象引用并与许多其他对象通信,因此重用对象很困难。
  3. 分布在几个类中的行为应该是可定制的,而无需大量的子类化。

六、中介者模式在Java中的实际应用

  1. java.util.Timer的所有scheduleXXX()方法。
  2. java.util.concurrent.Executor#execute()
  3. java.util.concurrent.ExecutorService的submit()和invokeXXX()方法。
  4. java.util.concurrent.ScheduledExecutorService的scheduleXXX()方法。
  5. java.lang.reflect.Method#invoke()
  6. Java消息服务(JMS)使用中介者来处理客户端和服务器之间的消息交换。
  7. JavaBeans属性更改支持类(java.beans.PropertyChangeSupport)充当中介者,处理关于属性更改的bean之间的通信。

七、中介者模式的好处和权衡

好处:

  1. 减少程序组件之间的耦合,促进更好的组织和更易于维护。
  2. 集中控制。中介者模式集中了控制逻辑,使其更易于理解和管理。

权衡:

  1. 中介者可能会成为与系统中所有类耦合的上帝对象,承担过多的责任和复杂性。

八、源码下载

中介者模式示例代码下载

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值