// The mediator interface declares a method used by components // to notify the mediator about various events. The mediator may // react to these events and pass the execution to other // components. interfaceMediator is method notify(sender: Component, event: string)
// The concrete mediator class. The intertwined web of // connections between individual components has been untangled // and moved into the mediator. classAuthenticationDialogimplementsMediator is private field title: string private field loginOrRegisterChkBx: Checkbox private field loginUsername, loginPassword: Textbox private field registrationUsername, registrationPassword, registrationEmail: Textbox private field okBtn, cancelBtn: Button
constructor AuthenticationDialog() is // Create all component objects by passing the current // mediator into their constructors to establish links.
// When something happens with a component, it notifies the // mediator. Upon receiving a notification, the mediator may // do something on its own or pass the request to another // component. method notify(sender, event) is if(sender == loginOrRegisterChkBx and event == "check") if (loginOrRegisterChkBx.checked) title = "Log in" // 1. Show login form components. // 2. Hide registration form components. else title = "Register" // 1. Show registration form components. // 2. Hide login form components
if (sender == okBtn && event == "click") if (loginOrRegister.checked) // Try to find a user using login credentials. if (!found) // Show an error message above the login // field. else // 1. Create a user account using data from the // registration fields. // 2. Log that user in. // ...
// Components communicate with a mediator using the mediator // interface. Thanks to that, you can use the same components in // other contexts by linking them with different mediator // objects. classComponent is field dialog: Mediator
constructor Component(dialog) is this.dialog = dialog
method click() is dialog.notify(this, "click")
method keypress() is dialog.notify(this, "keypress")
// Concrete components don't talk to each other. They have only // one communication channel, which is sending notifications to // the mediator. classButtonextendsComponent is // ...
classTextboxextendsComponent is // ...
classCheckboxextendsComponent is method check() is dialog.notify(this, "check") // ...
from __future__ import annotations from abc import ABC
classMediator(ABC): """ The Mediator interface declares a method used by components to notify the mediator about various events. The Mediator may react to these events and pass the execution to other components. """
defnotify(self, sender: object, event: str) -> None: if event == "A": print("Mediator reacts on A and triggers following operations:") self._component2.do_c() elif event == "D": print("Mediator reacts on D and triggers following operations:") self._component1.do_b() self._component2.do_c()
classBaseComponent: """ The Base Component provides the basic functionality of storing a mediator's instance inside component objects. """
""" Concrete Components implement various functionality. They don't depend on other components. They also don't depend on any concrete mediator classes. """
classComponent1(BaseComponent): defdo_a(self) -> None: print("Component 1 does A.") self.mediator.notify(self, "A")
defdo_b(self) -> None: print("Component 1 does B.") self.mediator.notify(self, "B")
classComponent2(BaseComponent): defdo_c(self) -> None: print("Component 2 does C.") self.mediator.notify(self, "C")
defdo_d(self) -> None: print("Component 2 does D.") self.mediator.notify(self, "D")
if __name__ == "__main__": # The client code. c1 = Component1() c2 = Component2() mediator = ConcreteMediator(c1, c2)
print("Client triggers operation A.") c1.do_a()
print("\n", end="")
print("Client triggers operation D.") c2.do_d()
Output.txt:执行结果
1 2 3 4 5 6 7 8 9 10 11
Client triggers operation A. Component 1 does A. Mediator reacts on A and triggers following operations: Component 2 does C.
Client triggers operation D. Component 2 does D. Mediator reacts on D and triggers following operations: Component 1 does B. Component 2 does C.
// Station has `accept` and `depart` methods, // but it also implements `Mediator`. letmut station = TrainStation::default();
// Station is taking ownership of the trains. station.accept(train1); station.accept(train2);
// `train1` and `train2` have been moved inside, // but we can use train names to depart them. station.depart("Train 1"); station.depart("Train 2"); station.depart("Train 3");
// Station has `accept` and `depart` methods, // but it also implements `Mediator`. letmut station = TrainStation::default();
// Station is taking ownership of the trains. station.accept(train1); station.accept(train2);
// `train1` and `train2` have been moved inside, // but we can use train names to depart them. station.depart("Train 1"); station.depart("Train 2"); station.depart("Train 3"); }
输出
1 2 3 4 5 6
Passenger train Train 1: Arrived Freight train Train 2: Arrival blocked, waiting Passenger train Train 1: Leaving Freight train Train 2: Arrived Freight train Train 2: Leaving 'Train 3' is not on the station!