DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Please enter at least three characters to search
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Zones

Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks

Last call! Secure your stack and shape the future! Help dev teams across the globe navigate their software supply chain security challenges.

Modernize your data layer. Learn how to design cloud-native database architectures to meet the evolving demands of AI and GenAI workloads.

Releasing software shouldn't be stressful or risky. Learn how to leverage progressive delivery techniques to ensure safer deployments.

Avoid machine learning mistakes and boost model performance! Discover key ML patterns, anti-patterns, data strategies, and more.

Related

  • Cutting-Edge Object Detection for Autonomous Vehicles: Advanced Transformers and Multi-Sensor Fusion
  • Inheritance in PHP: A Simple Guide With Examples
  • Writing DTOs With Java8, Lombok, and Java14+
  • Graph API for Entra ID (Azure AD) Object Management

Trending

  • The Role of Retrieval Augmented Generation (RAG) in Development of AI-Infused Enterprise Applications
  • It’s Not About Control — It’s About Collaboration Between Architecture and Security
  • The Modern Data Stack Is Overrated — Here’s What Works
  • A Guide to Developing Large Language Models Part 1: Pretraining
  1. DZone
  2. Coding
  3. Languages
  4. Practical PHP Patterns: Mediator

Practical PHP Patterns: Mediator

By 
Giorgio Sironi user avatar
Giorgio Sironi
·
Mar. 02, 10 · News
Likes (0)
Comment
Save
Tweet
Share
12.0K Views

Join the DZone community and get the full member experience.

Join For Free
The pattern of the day is the Mediator one. The intent of this pattern is encapsulating the interactions of a set of objects, preventing aggressive coupling from each of them towards the other ones. A Mediator acts as a central point of convergence between the Colleague objects.

In any domain there are many operations that do not fit on existent, modelled-from-reality objects, and if forced as methods of an already existent class would add a dependency towards a possibly unrelated collaborator. This approach would result in a web of highly interrelated Colleague objects and not in the Ravioli code we want to work with. The Colleague objects should be kept loosely coupled to avoid having to reference them as a whole any time one of them is needed from a Client.

The solution to this common problem is implementing the Mediator pattern. When an object's relationships and dependencies start to conflict with its business responsibility (the reason it was created in the first place), we should introduce a Mediator that coordinates the workflow between the coupled objects, freeing them from this form of coupling; dependencies can be established from the Colleagues towards the Mediator and/or from the Mediator towards the Colleagues. Both directions of those dependencies can be broken with an interface AbstractColleague or AbstractMediator, if necessary.

No object is an island, and each object in an application must cooperate with other parts of the graph to get its job done and addressing one concern. Since the interactions are a source of coupling, a Mediator is one of the most effective patterns in limiting it, although, if abused, it may render more difficult to write cohesive classes.
As a practical example, Services in Domain-Driven Design are Mediators between Entities. For a php-related example, Zend_Form decorating and filtering capabilities are actually the implementation of a simple Mediator between Zend_Form_Decorator and Zend_Filter instances. The same goes for validation using Zend_Validate objects. Making every filter referencing the next one would build a Chain of Responsibility which potential would be unused.

When a Mediator must listen to Colleagues events, it is often implemented as an Observer resulting in a blackboard object where some Colleagues write and other ones read. Events are pushed to the Mediator from a Colleague, before it delivers them to the others subscribed Colleagues. There is no knowledge of others Colleagues in anyone of them: this architecture is successfully used in the Dojo javascript library shipped with Zend Framework.

Another advantage of this pattern is the variation of the objects involved in the computation: this goal can be achived by configuring the Mediator differently, whereas instancing interrelated objects would be an noncohesive operation and the collaboration relationships would be scattered between different containers or factories.

Participants
  • Colleague: focuses on its responsibility, communicating only with a Mediator or AbstractMediator.
  • Mediator: coordinates the work of a set composed by several Colleagues (AbstractColleagues).
  • AbstractMediator, AbstractColleague: optional interfaces that decouple from the actual implementation of these roles. There may be more than one AbstractColleague role.
The code sample implements a filtering process for a form input that resembles Zend_Form_Element's feature.

<?php
/**
* AbstractColleague.
*/
interface Filter
{
public function filter($value);
}

/**
* Colleague. We decide in the implementation phase
* that Colleagues should not know the next Colleague
* in the chain, resorting to a Mediator to link them together.
* This choice succesfully avoids a base abstract class
* for Filters.
* Remember that this is an example: it is not only
* Chain of Responsibility that can be alternatively implemented
* as a Mediator.
*/
class TrimFilter implements Filter
{
public function filter($value)
{
return trim($value);
}
}

/**
* Colleague.
*/
class NullFilter implements Filter
{
public function filter($value)
{
return $value ? $value : '';
}
}

/**
* Colleague.
*/
class HtmlEntitiesFilter implements Filter
{
public function filter($value)
{
return htmlentities($value);
}
}

/**
* The Mediator. We avoid referencing it from ConcreteColleagues
* and so the need for an interface. We leave the implementation
* of a bidirectional channel for the Observer pattern's example.
* This class responsibility is to store the value and coordinate
* filters computation when they have to be applied to the value.
* Filtering responsibilities are obviously a concern of
* the Colleagues, which are Filter implementations.
*/
class InputElement
{
protected $_filters;
protected $_value;

public function addFilter(Filter $filter)
{
$this->_filters[] = $filter;
return $this;
}

public function setValue($value)
{
$this->_value = $this->_filter($value);
}

protected function _filter($value)
{
foreach ($this->_filters as $filter) {
$value = $filter->filter($value);
}
return $value;
}

public function getValue()
{
return $this->_value;
}
}

$input = new InputElement();
$input->addFilter(new NullFilter())
->addFilter(new TrimFilter())
->addFilter(new HtmlEntitiesFilter());
$input->setValue(' You should use the <h1>-<h6> tags for your headings.');
echo $input->getValue(), "\n";
Mediator (software) PHP Object (computer science)

Published at DZone with permission of Giorgio Sironi, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

Related

  • Cutting-Edge Object Detection for Autonomous Vehicles: Advanced Transformers and Multi-Sensor Fusion
  • Inheritance in PHP: A Simple Guide With Examples
  • Writing DTOs With Java8, Lombok, and Java14+
  • Graph API for Entra ID (Azure AD) Object Management

Partner Resources

×

Comments
Oops! Something Went Wrong

The likes didn't load as expected. Please refresh the page and try again.

ABOUT US

  • About DZone
  • Support and feedback
  • Community research
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 100
  • Nashville, TN 37211
  • support@dzone.com

Let's be friends:

Likes
There are no likes...yet! 👀
Be the first to like this post!
It looks like you're not logged in.
Sign in to see who liked this post!