0% found this document useful (0 votes)
16 views

Mediator Pattern

Uploaded by

Serenety_ed
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
16 views

Mediator Pattern

Uploaded by

Serenety_ed
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 9

The **Mediator Pattern** is a behavioral design pattern that defines an

object (the **mediator**) responsible for managing communication


between a set of objects. This pattern is used to reduce the complexity
of communication between objects by centralizing the interaction in a
single mediator rather than allowing objects to communicate with each
other directly. The primary goal of the Mediator Pattern is to promote
loose coupling and to simplify object interactions in complex systems.

### The Problem the Mediator Pattern Solves

In many systems, objects need to communicate with each other, often in


a way that requires direct references between them. When objects are
tightly coupled, it can become challenging to maintain or extend the
system because changes in one object can affect many other objects.
Furthermore, if there are multiple objects interacting in a web-like
structure (i.e., "many-to-many" communication), this can result in a
highly complex and fragile system where the addition of a new object or
modification of an existing object causes ripple effects throughout the
entire system.

Consider a scenario where several components in a user interface (UI)


need to interact with each other, such as buttons, text fields, and
dropdown menus. If these components directly interact with each other,
the system can quickly become unmanageable. For example, a button
might need to update a text field, while the text field's value might need
to affect the visibility of a dropdown menu, and so on. Directly wiring
these interactions together can lead to a tangled mess of dependencies
that are hard to debug or extend.

The **Mediator Pattern** solves this problem by centralizing


communication in a single object—the mediator—which acts as an
intermediary between all the components. Each component interacts
with the mediator, rather than interacting with other components directly.
This reduces dependencies between the components and makes the
system more flexible and maintainable.

### Structure of the Mediator Pattern

The Mediator Pattern involves the following participants:

1. **Mediator (Interface or Abstract Class)**: This defines the interface


for communicating with colleague objects. It might have a method like
`notify()` to handle communication between objects.

2. **ConcreteMediator**: This class implements the Mediator interface


and coordinates the communication between the colleague objects. The
`ConcreteMediator` is responsible for directing the interaction between
different components. It holds references to the colleague objects and
ensures that they can communicate with each other, without knowing
the details of how the interaction works.

3. **Colleague Objects**: These are the objects that need to


communicate with each other but do so through the mediator rather than
directly. Colleague objects are typically unaware of the other colleagues
and only communicate with the mediator. Each colleague may use a
method in the mediator to notify or request actions from other
colleagues.

### Example in a User Interface

Imagine a scenario where we have a UI with a **TextBox**, a


**CheckBox**, and a **Button**. Let's consider the following behavior:
- If the checkbox is checked, the button should be enabled.

- If the checkbox is unchecked, the button should be disabled.

- If the text in the TextBox exceeds a certain length, the button should be
disabled, regardless of the checkbox.

Without a mediator, the TextBox would need to directly interact with the
CheckBox and Button, and vice versa. If you added a new component,
say a **Label**, it would increase the complexity of communication,
requiring more direct interactions.

Using the Mediator Pattern, we would have a `FormMediator` that


coordinates communication between the `TextBox`, `CheckBox`, and
`Button`. The components would not be aware of each other’s
implementation; instead, they would only interact with the mediator.
Here’s a simple illustration:

```java

// Mediator Interface

public interface Mediator {

void notify(Object sender, String event);

// Concrete Mediator

public class FormMediator implements Mediator {

private TextBox textBox;

private CheckBox checkBox;


private Button button;

public FormMediator(TextBox textBox, CheckBox checkBox, Button


button) {

this.textBox = textBox;

this.checkBox = checkBox;

this.button = button;

@Override

public void notify(Object sender, String event) {

if (sender == checkBox && event.equals("checked")) {

button.setEnabled(true);

} else if (sender == checkBox && event.equals("unchecked")) {

button.setEnabled(false);

} else if (sender == textBox && event.equals("textChanged")) {

if (textBox.getText().length() > 10) {

button.setEnabled(false);

} else {

button.setEnabled(true);

}
}

// Colleague (TextBox)

public class TextBox {

private Mediator mediator;

private String text;

public TextBox(Mediator mediator) {

this.mediator = mediator;

public void setText(String text) {

this.text = text;

mediator.notify(this, "textChanged");

public String getText() {

return text;

// Colleague (CheckBox)
public class CheckBox {

private Mediator mediator;

private boolean checked;

public CheckBox(Mediator mediator) {

this.mediator = mediator;

public void setChecked(boolean checked) {

this.checked = checked;

mediator.notify(this, checked ? "checked" : "unchecked");

public boolean isChecked() {

return checked;

// Colleague (Button)

public class Button {

private boolean enabled;


public void setEnabled(boolean enabled) {

this.enabled = enabled;

public boolean isEnabled() {

return enabled;

```

In this example, when a user interacts with the `TextBox` or the


`CheckBox`, they notify the mediator (i.e., `FormMediator`). The mediator
then updates the state of the `Button` accordingly. The `TextBox`,
`CheckBox`, and `Button` objects are completely decoupled from one
another.

### Benefits of the Mediator Pattern

1. **Reduced Complexity**: By centralizing communication in a single


mediator, we avoid the need for a complex web of dependencies
between objects. This simplifies maintenance and debugging.

2. **Loose Coupling**: Colleague objects no longer need to know about


the specific details of other colleague objects. They only need to know
about the mediator, which leads to loose coupling. This makes it easier
to change or add components without affecting others.
3. **Simplified Object Interactions**: The mediator takes care of the logic
of how objects should interact, meaning the individual objects don’t
need to handle the complexity of these interactions. This results in more
focused and simpler classes.

4. **Centralized Control**: The mediator provides a single point of


control for object interactions, making it easier to manage the flow of
communication. It is particularly useful when complex workflows or
interactions between multiple objects need to be managed.

5. **Improved Reusability**: Because colleague objects are not aware of


each other’s implementation, they can be reused in different contexts, as
long as a suitable mediator is available.

### Drawbacks of the Mediator Pattern

1. **Mediator Becomes a God Object**: One of the risks of using the


Mediator Pattern is that the mediator can become overly complex if it
needs to handle too many interactions or maintain too many
relationships between objects. It can end up taking on too much
responsibility, becoming a "God Object" that is difficult to manage and
maintain.

2. **Overhead for Simple Systems**: In simpler systems, where


interactions between objects are minimal, the Mediator Pattern might
introduce unnecessary overhead. The added abstraction could be
overkill if the system doesn’t have complex communication
requirements.
3. **Difficulty in Extending the Mediator**: As the system grows, it may
become harder to extend the mediator to support new types of
interactions. Adding new behavior to the mediator might require
touching many parts of the mediator’s code, which can become brittle
over time.

### When to Use the Mediator Pattern

- **Complex Communication**: When many objects need to


communicate in complex ways, and direct communication between
objects would result in a tangled, difficult-to-manage system.

- **Loose Coupling**: When you need to reduce dependencies between


components and ensure that components can evolve independently.

- **Centralized Control**: When you need a single place to manage


interactions and ensure that objects behave in a coordinated manner.

### Conclusion

The **Mediator Pattern** is a powerful tool for simplifying complex


systems where multiple objects need to interact. By centralizing
communication in a mediator, the pattern promotes loose coupling,
reduces complexity, and helps keep objects focused on their primary
responsibilities. While it’s not without potential drawbacks, especially in
highly complex systems, the Mediator Pattern remains an essential
design pattern in the toolkit of software developers aiming to manage
object interactions more effectively.

You might also like