- C++ Home
- C++ Overview
- C++ Environment Setup
- C++ Basic Syntax
- C++ Comments
- C++ Hello World
- C++ Omitting Namespace
- C++ Tokens
- C++ Constants/Literals
- C++ Keywords
- C++ Identifiers
- C++ Data Types
- C++ Numeric Data Types
- C++ Character Data Type
- C++ Boolean Data Type
- C++ Variable Types
- C++ Variable Scope
- C++ Multiple Variables
- C++ Input Output Operations
- C++ Basic Input/Output
- C++ Cin
- C++ Cout
- C++ Manipulators
- Type System & Data Representation
- C++ Modifier Types
- C++ Storage Classes
- C++ Constexpr Specifier
- C++ Numbers
- C++ Enumeration
- C++ Enum Class
- C++ References
- C++ Date & Time
- C++ Operators
- C++ Operators
- C++ Arithmetic Operators
- C++ Relational Operators
- C++ Logical Operators
- C++ Bitwise Operators
- C++ Assignment Operators
- C++ sizeof Operator
- C++ Conditional Operator
- C++ Comma Operator
- C++ Member Operators
- C++ Casting Operators
- C++ Pointer Operators
- C++ Operators Precedence
- C++ Unary Operators
- C++ Scope Resolution Operator
- C++ Control Statements
- C++ Decision Making
- C++ if Statement
- C++ if else Statement
- C++ Nested if Statements
- C++ switch Statement
- C++ Nested switch Statements
- C++ Loop Types
- C++ while Loop
- C++ for Loop
- C++ do while Loop
- C++ Foreach Loop
- C++ Nested Loops
- C++ Jump Statements
- C++ break Statement
- C++ continue Statement
- C++ goto Statement
- C++ Return Values
- C++ Strings
- C++ Strings
- C++ Loop Through a String
- C++ String Length
- C++ String Concatenation
- C++ String Comparison
- C++ Functions
- C++ Functions
- C++ Multiple Function Parameters
- C++ Recursive Function
- C++ Function Overloading
- C++ Function Overriding
- C++ Default Arguments
- C++ Arrays
- C++ Arrays
- C++ Multidimensional Arrays
- C++ Pointer to an Array
- C++ Passing Arrays to Functions
- C++ Return Array from Functions
- C++ Array Decay
- C++ Structure & Union
- C++ Structures
- C++ Unions
- C++ Class and Objects
- C++ Object Oriented
- C++ Classes & Objects
- C++ Class Member Functions
- C++ Class Access Modifiers
- C++ Static Class Members
- C++ Static Data Members
- C++ Static Member Function
- C++ Inline Functions
- C++ this Pointer
- C++ Friend Functions
- C++ Pointer to Classes
- C++ Constructors
- C++ Constructor & Destructor
- C++ Default Constructors
- C++ Parameterized Constructors
- C++ Copy Constructor
- C++ Constructor Overloading
- C++ Constructor with Default Arguments
- C++ Delegating Constructors
- C++ Constructor Initialization List
- C++ Dynamic Initialization Using Constructors
- C++ Destructors
- C++ Virtual Destructor
- C++ Inheritance
- C++ Inheritance
- C++ Multiple Inheritance
- C++ Multilevel Inheritance
- C++ Object-oriented
- C++ Overloading
- C++ Polymorphism
- C++ Abstraction
- C++ Encapsulation
- C++ Interfaces
- C++ Virtual Function
- C++ Pure Virtual Functions & Abstract Classes
- C++ Override Specifiers
- C++ Final Specifiers
- C++ Design Patterns
- C++ Creational Design Patterns
- C++ Singleton Design Pattern
- C++ Factory Method Design Pattern
- C++ Abstract Factory Pattern
- C++ Prototype Design Pattern
- C++ Structural Design Patterns
- C++ Facade Design Pattern
- C++ Iterator Design Pattern
- C++ Mediator Design Pattern
- C++ Memento Design Pattern
- C++ Observer Design Pattern
- C++ State Design Pattern
- C++ File Handling
- C++ Files and Streams
- C++ Reading From File
- C++ Advanced
- C++ Exception Handling
- C++ Dynamic Memory
- C++ Move Semantics
- C++ Namespaces
- C++ Templates
- C++ Preprocessor
- C++ Signal Handling
- C++ Multithreading
- C++ Web Programming
- C++ Socket Programming
- C++ Concurrency
- C++ Advanced Concepts
- C++ Lambda Expression
- C++ nullptr
- C++ unordered_multiset
- C++ Chain of Responsibility
- C++ Structural Design Patterns
- C++ Adapter Pattern
- C++ Bridge Pattern
- C++ Composite Pattern
- C++ Decorator Pattern
- C++ Flyweight Pattern
- C++ Command Pattern
- C++ Proxy Pattern
Mediator Design Pattern in C++
Mediator Design Pattern is a way to make communication between different objects or classes much simpler. Instead of having every object talk directly to every other object, which can get very confusing, we use a special class called the mediator. The mediator acts like a middleman and handles all the messages between objects. This makes the code easier to manage and change later because the objects don't need to know about each other.
Let's make this even clearer with a simple example from real life. Imagine an airport. There are many airplanes, and they all need to communicate about when to take off or land. If every airplane tried to talk to every other airplane, it would be chaos! Instead, there is a control tower. The control tower is the mediator. All airplanes talk only to the control tower, and the tower tells each airplane what to do. This keeps everything organized and safe.
So, in programming, the mediator pattern works just like the control tower at the airport. It helps different parts of a program communicate in an organized way, making the whole system easier to understand and maintain.
Components of Mediator Design Pattern
Following are the main components of the Mediator Design Pattern −
- Mediator − Think of this as the main organizer or the middleman. It's a special class that helps different parts of the program talk to each other. Instead of everyone talking to everyone, they all talk to the mediator.
- ConcreteMediator − This is the real middleman in action. It knows about all the different parts (objects) and helps them send messages to each other. If one part wants to talk to another, it tells the mediator, and the mediator passes the message along.
- Colleague − These are the different parts or objects in your program that need to communicate. Each one knows about the mediator, but they don't know about each other. If they want to send a message, they go through the mediator.
- ConcreteColleague − These are the actual objects doing the work in your program. They use the mediator to talk to other objects. For example, in a chat room, each user is a ConcreteColleague, and they send messages through the chat room (the mediator).
C++ Implementation of Mediator Design Pattern
In this section, we will implement a simple mediator pattern example where we have a chat room that acts as a mediator between different users.
Steps to Implement Mediator Design Pattern in C++
Step 1: Create the Mediator Interface − This is like making a set of rules for how the middleman (mediator) will help others talk to each other. It just says what the mediator should be able to do, but not how.
Step 2: Make the Real Mediator Class − Here, you actually build the middleman. This class knows about everyone who needs to talk and helps them send messages to each other.
Step 3: Create the Colleague Interface − This is a simple plan for all the people (objects) who want to talk to each other. It says what each one should be able to do, like send a message.
Step 4: Build the Real Colleague Classes − Now you make the actual people (objects) who will use the mediator to talk. Each one uses the middleman instead of talking directly to others.
Step 5: See How It Works Together − Put everything together and show how the objects use the mediator to send messages. This is where you see the pattern in action, just like people using a group chat to talk instead of calling each other one by one.
C++ Code Example of Mediator Design Pattern
Following is a simple C++ code example demonstrating the Mediator Design Pattern −
#include <iostream>
#include <string>
#include <vector>
using namespace std;
// Mediator Interface
class ChatMediator {
public:
virtual void showMessage(const string &user, const string &message) = 0;
};
// Concrete Mediator
class ChatRoom : public ChatMediator {
private:
vector<string> users;
public:
void addUser(const string &user) {
users.push_back(user);
}
void showMessage(const string &user, const string &message) override {
cout << user << ": " << message << endl;
}
};
// Colleague Interface
class User {
protected:
ChatMediator *mediator;
string name;
public:
User(ChatMediator *med, const string &n) : mediator(med), name(n) {}
virtual void sendMessage(const string &message) = 0;
};
// Concrete Colleague
class ChatUser : public User {
public:
ChatUser(ChatMediator *med, const string &n) : User(med, n) {}
void sendMessage(const string &message) override {
mediator->showMessage(name, message);
}
};
int main() {
ChatRoom chatRoom;
ChatUser user1(&chatRoom, "Alice");
ChatUser user2(&chatRoom, "Bob");
ChatUser user3(&chatRoom, "Charlie");
chatRoom.addUser("Alice");
chatRoom.addUser("Bob");
chatRoom.addUser("Charlie");
user1.sendMessage("Hello, everyone!");
user2.sendMessage("Hi Alice!");
user3.sendMessage("Hey folks, what's up?");
return 0;
}
Following is the output of the above code −
Alice: Hello, everyone! Bob: Hi Alice! Charlie: Hey folks, what's up?
In this example, we have a ChatMediator interface, which is just a set of rules for how messages should be shown. The ChatRoom class follows these rules and acts as the main helper, or "middleman," for all the users. The User class is like a basic plan for anyone who wants to join the chat, and the ChatUser class is a real person in the chat who sends messages using the chat room.
Here's how it works: When a user wants to send a message, they don't talk directly to other users. Instead, they tell the chat room (the mediator), and the chat room takes care of showing the message. This keeps things simple and organized, because users don't need to know about each other-they just use the chat room to communicate.
When you run the code above, you'll see that all the users send their messages through the chat room. This is a clear example of how the Mediator Design Pattern helps different parts of a program talk to each other in a simple and tidy way, without getting mixed up or confused.
Pros and Cons of Mediator Design Pattern
Like any design pattern, the Mediator Design Pattern has its good sides and its not-so-good sides.
| Pros | Cons |
|---|---|
| Makes it easier for different parts of your program to work together without being directly connected. This means if you change one part, you don't have to change all the others. | If too many things depend on the mediator, it can become overloaded and slow things down. |
| Puts all the rules for how things talk to each other in one place, so it's simpler to see and fix how communication works. | Adds an extra step (the mediator) between objects, which can make the program a bit more complicated. |
| Helps different parts of your program talk to each other, even if they don't know about each other at all. | If you're not careful, the mediator can become too big and hard to manage. |
| Makes your code easier to read and understand because everything goes through the mediator. | Because messages go through the mediator, it can be harder to figure out where a problem is if something goes wrong. |
| If you want to change how things communicate, you only need to update the mediator, not every single part. | Sometimes, using a mediator too much can make the other parts less independent and flexible. |
When to Use Mediator Design Pattern
The Mediator Design Pattern is particularly useful in the following scenarios −
- If your program has many different parts that all need to talk to each other, things can quickly get confusing. For example, imagine you have lots of buttons, windows, or users, and they all need to send messages or updates to each other. The Mediator pattern helps keep everything organized by letting each part talk only to a central helper, instead of directly to every other part.
- It's much easier to change your code later if each part only talks to the mediator (the middleman). If you ever want to change how things communicate, you just update the mediator, and you don't have to rewrite everything else. This saves time and makes your program easier to maintain.
- eeping all the rules for how things talk to each other in one place makes your program simpler to understand and fix. Instead of searching through lots of different files or classes to figure out how communication works, you just look at the mediator.
- Different parts of your program don't need to know about each other at all. This means you can add, remove, or change parts without worrying about breaking the rest of your program.
- Your code becomes much easier to read and understand. By using a mediator, you avoid a tangled mess of connections, and it's clear how everything communicates. This makes it easier for you or anyone else to work with your code in the future.
Real-World Examples of Mediator Design Pattern
Some real-world examples of the Mediator Design Pattern include −
- When you look at how airplanes work at an airport, you can see the mediator pattern in action. All the airplanes do not talk to each other directly. Instead, they all talk to the control tower. The control tower tells each airplane when it is safe to land or take off. This keeps everything safe and organized. The control tower is like a helpful friend who makes sure everyone knows what to do.
- In a group chat, people do not send messages straight to each other. Everyone sends their message to the chat room. The chat room then shares the message with everyone else. This means people do not need to know who is in the chat or how to reach them. The chat room helps everyone stay connected easily.
- When you use an app with buttons and windows, the buttons do not talk to each other or to the windows directly. There is a central part of the program that listens to all the buttons and windows. This central part decides what should happen when you click a button or open a window. It helps everything work together smoothly, just like a helpful guide.
- If you think about a big event like a wedding, the guests do not talk to every vendor, such as the caterer, photographer, or band, by themselves. There is an event organizer who talks to everyone and makes sure things happen at the right time. The event organizer helps everyone work together and keeps things running smoothly.
- In some offices, there is a manager who gives out tasks to different workers and makes sure everyone knows what to do. The workers do not have to talk to each other about who does what. The manager handles all the communication and helps everyone stay on track.
Conclusion
In this chapter, we have learned about the Mediator Design Pattern, its components, implementation in C++, pros and cons, and real-world examples. The Mediator Design Pattern is a powerful tool for managing complex communication between objects while promoting loose coupling and maintainability. By using this pattern, developers can create more flexible and scalable systems that are easier to understand and maintain.