In this lesson, you will learn how to use the Mediator pattern to prevent complex "spaghetti" dependencies by routing all component communication through a central, trait-based hub.
The Problem: Chaotic Coupling
As systems grow, components often begin to talk directly to one another. If a Button needs to tell a Label to update its text and a Logger to record the event, the Button must hold references to both. This creates tight coupling: changing one component forces you to update every other component that references it.
The Solution: The Mediator Pattern
Instead of direct chatter, we introduce a Mediator. Components no longer know about each other; they only know about a Mediator trait. When a component experiences a change (like a user click), it sends a notification to the mediator. The mediator then decides how to broadcast that event to other components.
Implementation Illustration
In Rust, we define the communication interface via a trait, ensuring the mediator remains agnostic of specific concrete types:
trait Mediator {
fn notify(&self, sender: &str, event: &str);
}
struct UIMediator {
// Stores references to components
label: String,
logger: String,
}
impl Mediator for UIMediator {
fn notify(&self, sender: &str, event: &str) {
if event == "click" {
println!("Mediator: Updating label and logging click from {}", sender);
}
}
}
By passing a &dyn Mediator to your components, they become perfectly decoupled. The Button doesn't need to know the Label exists; it only needs to know that a mediator exists to handle the consequences of its actions. This keeps your architecture clean, testable, and modular, as components can be swapped or modified without rippling changes throughout your entire codebase.
The Mediator acts as a "traffic controller," enforcing a protocol where no component reaches out directly to another, preventing the architectural drift that usually occurs when objects become too "chatty" with their neighbors.
Key Takeaway: The Mediator pattern replaces direct object-to-object coupling with a centralized trait interface, ensuring that components only need to know about the mediator, not each other.