核心思想:通过引入一个中介对象来降低对象之间的直接交互。在该模式中,调停者对象充当了所有相关对象之间的协调者,其主要作用是接收并处理这些对象发出的请求。通过使用调停者模式,可以减少对象之间的依赖性,从而提高系统的可维护性和可扩展性
场景:假设在一个游戏中,现在有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判断可以考虑使用策略模式来优化。