8000 Observer instead of Mediator pattern by ruff3d · Pull Request #9912 · symfony/symfony-docs · GitHub
[go: up one dir, main page]

Skip to content

Observer instead of Mediator pattern #9912

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 4 commits into from
Closed

Conversation

ruff3d
Copy link
Contributor
@ruff3d ruff3d commented Jun 11, 2018

Actually Event Dispatcher component implements Observer pattern (GoF) but not a Mediator.
I think we should change this description so as not to confuse users in the future.

Actually EventDespacher component implements Observer pattern (GoF) but not a Mediator.
I think we should change this description so as not to confuse users in the future.
@javiereguiluz
Copy link
Member

@ruff3d thanks for proposing this improvement. Let me ask @hhamon, who is an expert in both Symfony and design patterns, to see if he can verify this change. Thanks!

@HeahDude
Copy link
Contributor

The EventDispatcher is a clever mix of both, but the Mediator is more suited if we had to choose one.

@Pierstoval
Copy link
Contributor

@HeahDude
Copy link
Contributor

Because the actual observers are registered listeners.

@jakzal
Copy link
Contributor
jakzal commented Jun 22, 2018

re #2817

To me it always seemed like it implements none of the two.

@wouterj
Copy link
Member
wouterj commented Jun 22, 2018

EventDispatcher implements the Mediator pattern. See also the detailed PR description in #2817

In Observer, a subject class keeps track of it's own observers and notifies them. It would look like:

class UpdateBlogPostHandler implements SubjectInterface
{
    use SubjectTrait;

    public function handle(UpdateBlogPost $command)
    {
        // ... update blog post

        $this->notify(new BlogPostUpdated($command->getId(), $command->getNewBody());
    }
}

Whereas the Mediator pattern uses a "god class" that keeps track of all subjects and all observers (like Symfony's EventDispatcher):

class UpdateBlogPostHandler
{
    private $mediator;

    public function __construct(EventDispatcherInterface $mediator)
    {
        $this->mediator = $mediator;
    }

    public function handle(UpdateBlogPost $command)
    {
        // ... update blog post

        $this->mediator->notify(new BlogPostUpdated($command->getId(), $command->getNewBody());
    }
}

@Pierstoval
Copy link
Contributor

Change in docs can mention a mix of Observer and Mediator patterns with both links, WDYT?

@javiereguiluz
Copy link
Member

The replies so far are: Mediator, Both and None ... so this is getting more and more complicated to decide 😱

@HeahDude
Copy link
Contributor

The Mediator is the simplest way to define what the dispatcher is. The docs should be about its usage, not about going deep in its internal architecture conception explanation, IMHO we'd better keep the docs as is.

@Toflar
Copy link
Contributor
Toflar commented Jun 22, 2018

To me, the Symfony EventDispatcher clearly represents the Mediator pattern. The Observer pattern does not have any mediator class. You'd have many producers and the consumers register directly to the correct producer instead of having the mediator figure out which consumer needs to be called based on what producer dispatched an event. However, I feel like that these pattern names are used interchangeably. I would keep the docs as is though because imho it's technically correct.

@Pierstoval
Copy link
Contributor

I feel like that these pattern names are used interchangeably

No, they're not, but for the case of the Event Dispatcher, it kinda implements both patterns, that's all 😉

@javiereguiluz
Copy link
Member

Most of you mentioned that the component implements the two patterns. Could we reword this as follows then?

Original:

The Symfony EventDispatcher component implements the `Mediator`_ pattern
in a simple and effective way to make all these things possible and to make
your projects truly extensible.

Proposal:

The Symfony EventDispatcher component implements the `Mediator`_ and `Observer`_
design patterns to make all these things possible and to make your projects
truly extensible.

@HeahDude
Copy link
Contributor

Sounds good to me.

@javiereguiluz
Copy link
Member
javiereguiluz commented Jun 25, 2018

Thanks Denis. We merged in 2.8 branch and later we'll merge in the upper branches automatically.

javiereguiluz added a commit that referenced this pull request Jun 25, 2018
This PR was submitted for the 2.7 branch but it was merged into the 2.8 branch instead (closes #9912).

Discussion
----------

Observer instead of Mediator pattern

Actually Event Dispatcher component implements Observer pattern (GoF) but not a Mediator.
I think we should change this description so as not to confuse users in the future.

<!--

If your pull request fixes a BUG, use the oldest maintained branch that contains
the bug (see https://symfony.com/roadmap for the list of maintained branches).

If your pull request documents a NEW FEATURE, use the same Symfony branch where
the feature was introduced (and `master` for features of unreleased versions).

-->

Commits
-------

21ed3d2 Mention that the component implements both patterns
44e1e45 Update event_dispatcher.rst
f1b41ca Update event_dispatcher.rst
31a2315 Observer instead of Mediator pattern
@hhamon
Copy link
Contributor
hhamon commented Jun 26, 2018

To me the EventDispatcher is not really an Observer pattern implementation but it's clearly a Mediator. It just looks like an Observer pattern implementation in the fact that the event dispatcher maintains a collection of invokable objects.

However, in the Observer pattern, the Subject notifies a series of Observers when its internal state changes.

Consider a weather station (example taken from the Head First Design Patterns book), whenever the temperature sensor captures a new temperature, the weather station updates its internal state and notifies its many observers (for instance a LED display, alarm buzzer, etc.) to be aware of the new temperature.

The Symfony dispatcher doesn't maintain any state. When an event is dispatched, the series of listeners are invoked and receive the event. At the end of the dispatch method call, no state has been changed internally in the dispatcher. This is why we can't really consider the dispatcher a subject / observable and an event listener an observer.

The Mediator pattern is better suited as it's made for easing communication between objects by decoupling them. This is exactly what the dispatcher does. It mediates a message between subscribers.

My 2 cents.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

9 participants
0