My mailman doesn’t open my mail

or, implement the Mediator-Mini-Controller anti-pattern at your peril.

Postman Pat, Postman Pat, Postman Pat and his black and white cat. Early in the morning, just as day is dawning, he picks up all his post bags in his van.

Postman Pat doesn't open the mail. He's a very good mediator. (US translation – a Postman is a Mailman, they don’t really all have cats in the UK)

The robotlegs out-of-the-box implementation – what I like to think of as the standard issue trousers – relies on a version of the mediator pattern.

In this usage, the mediator’s job description is clear: deliver stuff from the application’s shared event dispatcher to the view, and from the view to the event dispatcher.

Like any good delivery service*, it also offers enhanced packaging for your exotic sending needs. Perhaps slipping your simple MouseEvent into an air-mail-approved CustomEvent envelope.

A good delivery service also varies its delivery approach based on the type of thing being delivered. Simple letters belong in the mail box. Packages requiring a signature lead to a knock on the door. Fragile goods are handled carefully.

But, and it’s a vital distinction, the mailman doesn’t open the mail.

Why shouldn’t the mailman open the mail?

Imagine that I asked my postie to start opening my post – or perhaps some of my post – and, based on the contents, delivering it, binning it, marking it urgent for me. Perhaps he could sort it into happy post and sad post? It would save me some work if he took it out of the envelopes first – after all, he passes my recycling bin on his way between the front door and the garden gate.

This might work out well for a while. But it would inevitably lead to problems. The return envelopes for starters – recycle, or use? How does the postie know whether I’m going to need them? And, yes, letters from people telling me to pay them money probably belong in the ‘sad’ pile – but what if the letter asks me to pay the deposit for something really cool?

And if something went missing – how would we know who’d misplaced the important letter?  Instead of just back tracking through my own actions, I’d be querying the postie’s movements as well.

The Mediator-Mini-Controller anti-pattern arises when your mediators start to get interested not just in what type of thing they’re delivering, but the contents of the parcel. You could also call it a Nosy Mediator.

A good mediator should know and care what to do with each type of information – but they shouldn’t vary their behaviours based on the values they find.

If your mediator reads the view’s mail, you end up with an application in which your logic is distributed over multiple mediators. It’s not just harder to keep DRY (because different but similar views may have mediators which would each need to implement some of this logic), it’s virtually impossible for someone looking from the outside to know where to start. And never forget, that someone is most likely going to be you, a year and several projects down the line.

If you do end up with logic – specifically a variation in behaviour (usually seen in the wild as a conditional such as if or switch) – in your mediator, at least call it what it is: SomeViewMediatorController.

And what the hell’s wrong with a Mediator Controller?

@stray_and_ruby One (wo-)man’s anti-pattern is another man’s pattern. #robotlegs’ mediator makes a great view-controller.
[@troygilbert, Nov 16, 2:10 am GMT]

Troy Gilbert points out that robotlegs mediators make excellent view-controllers. And they do – but a view-controller approach requires a different overall architecture to a mediator approach.  We can use mediators at various levels of granularity – mediating a group of screens, a screen, a component or even just a button. In robotlegs, anything that lands on the displayList can be mediated.  And with true mediators, you can take advantage of this in a relaxed way; the choice of whether to mediate a button or a group of buttons has no far reaching consequences for your application.

Can the same be said for view-controllers? Does it matter which views have controllers and which are just slaves to other views? I think it matters a great deal. You can still have a great, flexible, DRY design based on view-controllers, but almost certainly not just through the relaxed implementation of nosy mediators that open the view’s mail.

Troy is building some amazing stuff, so I’ve got no doubt that he is conscious in his decision to use mediators as controllers, and designs his apps accordingly; the mediator-mini-controller anti-pattern arises when you unconsciously use your mediators for controller responsibilities.

The Mediator-Mini-Controller anti-pattern is the micro-echo of feature creep. It seems innocuous – ‘just’ a teensy tiny switch based on the event properties.
Who could resist?

I’ll confess that I don’t always resist. And I nearly always regret it. To help my willpower, I like to think of my classes as reluctant employees. They’re just waiting for a chance to storm into my office (head) waving their contract and complaining that the task I’ve just given them wasn’t in their job description.

And they’d be right. If I want my mediators to act like controllers I should give them the promotion in both name and status, and treat them with the respect they deserve. Otherwise, I’ll stick with the fundamental social premise that the mailman should never open the mail.

* Like programming, delivery activites are carried out by women, of course, as well as men and cats.

About the Author

I'm an actionscript programmer living and working in a tiny village in the Yorkshire Dales, UK. I used to be a TV reporter, but my inner (and often outer) geek won. I also write stuff. Most recently Head First 2D Geometry.

Visit Stray's Website

Share the post

Delicious It Digg this! Stumble this! Share on Reddit Share on Buzz Share on FriendFeed
  • StimuliTV

    Hey Stray,

    Totally agree with you and have (so far) not had to mixin a view controller for my recent experiment http://deceptiveresolution.wordpress.com/2010/10/30/rockbot-soundcloud-stimuli-tv-robotlegs-port/ src – http://stimuli.tv/rockbot/111110/srcview/index.html

    I do however have a composite view that may need something along those lines which needs to be added so i’ll defo have a good hard think before hacking in a quick fix.

    Great article, made me think, thank you

    Doug

    • http://www.xxcoder.net Stray

      Thanks Doug – great to see example code that shows well behaved mediators in action!

      It’s the ‘good hard think’ that is important, I feel. In the end, sometimes we might decide to do something that breaks the rules, but often I think we stumble along just coding what’s in front of us, and that’s when unintentional coupling and ball-of-string stuff starts to happen.

      I’ll be interested to know what you end up considering in finding a solution for your composite view – the questions we ask shape the answers we come up with, so often I think learning is about finding new questions rather than new answers.

      Stray

  • http://troygilbert.com/ Troy Gilbert

    Thanks for the quote (and compliments on my work)! I definitely agree with the post’s sentiment that your code’s roles should be clearly defined *and* adhered to. It’s certainly the biggest mistake I make (other than underestimating dev schedules), particularly during a crunch.

    One of the biggest reasons I end up treating my mediators as view-controllers is my incredible distaste for putting AS3 script blocks in my MXML. As a result, some view logic ends up in the mediator as I like to keep my MXML purely declarative. Yes, this is basically code-behind.

    Also, I’m not completely sold on the event-map-to-command pattern (for my projects). Thus, the view-controller pattern fills in nicely. I think one reason may be that I generally build games and other real-time, view-centric apps. It feels like an excuse to say that, but I’ve certainly tried doing the full Robotlegs MVC split but the result has been a bulk of awkward code with no benefit.

    • http://www.xxcoder.net Stray

      I’m using ‘just as3′ (as Robert Penner would say). So I don’t have a lot of experience of the MXML scenario, but I can definitely see the attraction of keeping code out of your mxml! I did try flex briefly. It made me itchy.

      Am I naive in thinking that perhaps there should be a an [mxml] < -> [view logic] < -> [mediator] 3 part relationship in that scenario? The view logic outside of the mxml, but still separated from the mediator, as they do have different responsibilities?

      I really like the event / command pattern for my apps, but I’m not sure how it would work out for games. I’m doing very slow, action-then-something-happens-on-a-server kind of stuff mostly. But I’m not convinced it *can’t* work – I just had an idea for a game so I’ll see how that goes.

      I’m very glad to read that your biggest problem is the same as mine – underestimating dev schedules!

      Cheers,

      Stray

      • http://probertson.com/ Paul Robertson

        I’ve been thinking a lot about these things, and I also have come to the conclusion (or at least, the idea I want to test) of having a three part view stack with [core view] [view logic] [mediator]

        - [core view]: For a Flex app the “core view” would be the MXML. Like you I mostly do pure AS3 apps but I still find myself squirming with how much stuff I end up putting in my view classes. So for me the “core view” would basically be the layout/rendering logic with no app-specific logic at all.

        - [view logic]: I think of this conceptually as similar to a presentation model, though I’ve never built an app using that pattern so I could be mis-representing it. But to me this is where I would put the logic that you’re saying to pull out of the mediator — things like “if the user’s age is < N then change the layout in this certain way."

        - [mediator]: A very basic message bus — your "mail carrier" — that just listens for messages and passes them along between view and app.

        Anyway, those are my conceptual thoughts, though in terms of actual implementation I haven't put pixels to screen to try and actually work something out. At one point I think I read that Shaun's "Oil" might include the presentation model pattern, so I'm hoping that turns into something that matches my thinking (or that shows me an even better way that I didn't think of =)

        Thanks for another great post!

        • http://www.xxcoder.net Stray

          Thanks Paul – that does sound like a 3 part stack would meet your needs.

          I’m not sure that the ‘view logic’ always belongs in the view-logic area – I think as flash-folk we probably have a tendency to think in a view-oriented way, and spend a lot of time in view code, so that seems to be where it ends up.

          Lately I’ve been asking myself where else I might implement this logic (for example using a different view based on the user’s age) – I know it sure as hell doesn’t belong in the mediator. I *think* the optimisation is to move it higher up and achieve as much as possible through typing. So – allow a parent view to attach the correct view based on age… or if the age is fundamental to the app then put that piece of logic in to a command that is mapped to the user creation event, and dispatch a purposeful ‘UserEvent.CHILD_USER_CREATED’ or ‘UserEvent.ADULT_USER_CREATED’ event that gets acted upon.

          Interesting stuff though – so many ways to slice our cake! And yes – I’m sure Shaun will reveal something none of us had thought of :)

        • http://www.benclinkinbeard.com/ Ben Clinkinbeard

          You’ve basically just described the way I build Flex apps using the Presentation Model pattern and controllers. What you describe as view logic is the PM, and what you call mediator is (essentially) the controller.

          When using MXML and binding (even if not using Flex), in my opinion the PM pattern is best suited. Yes, you have a script block in the view, but all it does is declare the PM property. Other than that your view just sits there and looks pretty, relying on the PM for state and logic.

          I generally formulate each PM to act as a controller/model adapter for the view(s) that uses them, and to act as a bridge between the view and the rest of the app.

          • http://www.xxcoder.net Stray

            Thanks Ben,

            Having just said that I think AS3 ‘is’ the PM pattern, I can see that I really need to understand more about the Presentation Model pattern. Because it sounds like the dumb-view knows about the parent PM? And that’s not what my as3 views are like at all.

            Perhaps it doesn’t make as much sense in a ‘just as3′ situation without binding? (I know you can do binding in as3, I just choose not to – if I had that kind of rope I know I’d end up hanging myself with it).

            Maybe it’s just me, but binding reminds me of textfields in as1, where you could declare a variable that was linked to that field? I think I had a few bad experiences with that (being a stumbling as1 coder at the time).

            “I generally formulate each PM to act as a controller/model adapter for the view(s) that uses them, and to act as a bridge between the view and the rest of the app.”

            How do you justify that ‘and’? Or does it just not bother you? Pragmatic conscious choice to break SRP? Or is the SRP overrated generally?

          • http://www.benclinkinbeard.com/ Ben Clinkinbeard

            It looks like the threading is messed up, so I will just reply here.

            Yes, views know about their PM. While view mediators can keep views completely dumb, I like to say that the PM pattern keeps views “dumb enough”. They have a reference to the PM, and call its methods and such, but they still don’t have anything complex enough to warrant testing. Not even close.

            Removing binding from the equation definitely lessens the ease of implementing the PM pattern. In Fowler’s explanation of the pattern, he raises the point that some sort of synchronization mechanism is needed to keep the view in sync with the model. Binding is a great, mostly painless way to do just that.

            Regarding the “and”, I think that was more just how I was explaining the role I give PMs. They act as controller/model adapter for the view, that is their responsibility. As part of that responsibility they dispatch and listen for system events, and read from system models. Yes, I have “and” in there twice now, but you could also describe a view mediator by saying they listen for system events and notify the view and they listen for view events and notify the system. :)

          • http://www.xxcoder.net Stray

            Semantics have a lot to answer for, don’t they?

            It’s the collaborator explosion that I think the cleaner mediator pattern helps to avoid, but I think as long as there’s a consistent, considered approach, it’s all good.

            What really irks me is code that calls itself mediator but does a lot more.

            p.s. We have been rebuked on the RL forum for failing to enter into a fully fledged flaming pattern holy-war in this thread. Must try harder ;)

  • http://www.richardlord.net/ Richard Lord

    When I started reading this, I thought you were talking about pulling functionality from the controller into the mediator, which is clearly a bad idea. Even at the example I thought ‘that switch between two views should probably be in the controller’. But at the end I realised you’re talking about view logic and I couldn’t disagree more (Sorry).

    When I use Robotlegs I, like Troy, prefer the passive view pattern – a clean, simple view with logic in the mediator. When working with Flex it provides a clean separation and easy testing of the view logic. I haven’t used Robotlegs in a pure AS project, so can’t comment on whether that would make a difference.

    In relation to your metaphor I believe the mediator isn’t the postman. The event bus is the postman (and the whole delivery service). The mediator is the view’s personal assistant and as a PA it should open the mail.

    • http://www.xxcoder.net Stray

      Thanks Richard, I think what you’re drawing out here is the difference between choosing to implement a pattern mindfully vs thinking you’re doing one thing when in reality you end up doing a little bit of lots of different things.

      My suspicion is that often when people put logic in their mediator they start out by implementing a little bit of view logic, and then supplement it with a bit of application logic, and eventually it all becomes rather intertwined. As I said – the view-controller pattern is a good strategy, provided that’s what you know you’re doing, and you do it with intent.

      What causes problems is when people use a single class (the mediator) to implement view logic, application logic and the connection between the view and the application. Not only does the mediator end up with too many responsibilities, the project logic is distributed and repeated between multiple mediators which might be operating at all sorts of levels of granularity.

      If your logic is in your mediator then you can’t say that your view is truly isolated from your application workings. I think I’d see a 3 layer implementation as being much more clean and giving you the ability to make use of all the OO goodness of composition and multiple interfaces in the view controller, and the auto-magicness of the mediator map in the mediator.

      The eventBus is the central postal system in my analogy. The mediator is the individual postman. I think your view deserves a PA and a postman. The postman can hand the post to the PA, and the PA can open the mail on behalf of the view.

      • http://www.richardlord.net/ Richard Lord

        Thank you for your response. I think there is some misunderstanding, perhaps on both our sides. I am in no way suggesting that application logic (or the domain model, or the business rules, or whatever else we might call it) should be in the mediator. That would be a horrible idea. What I am stating is that placing the view logic (and no other logic) in the mediator works best for me. I have tried other patterns and after much deliberation this is the one that I favour.

        I use a fully passive view – one that is entirely decoupled from the rest of the application and is just a bunch of view display objects waiting to be used by the mediator. The mediator joins this view to the rest of the system by listening for events on the display objects in the view and dispatching appropriate events (with data gathered from the view where appropriate) onto the event bus, and by listening for events on the event bus and manipulating the view in response to those events and the data within them. Sometimes this might involve inserting text from the event into a text field, or sometimes it might involve a little view related logic to show and hide different display objects. The details may vary, but always this is functionality that necessarily happens within the view/mediator level of the application and cannot be handled within the commands, actors, services etc. So this in no way decreases the isolation of the view/mediator partnership from the rest of the system.

        This is what works best for me. Others may favour other options. As you say, it’s most important to be conscious of our choices and follow through on them. I absolutely agree that we should always be mindful of what we are doing when writing code, be consistent with the architecture, and try to minimise the technical debt (and be aware when we are creating that debt).

        Regarding the suggestion to use three levels in the view/mediator layer – I don’t like this idea. Robotlegs automatically creates a two link chain in the view layer, linking the view and the mediator. The easiest way to add a third link would be to use code-behind on the view, but that means using inheritance and like many I favour composition over inheritance. To use composition I’d want to inject this third object into the middle of the chain that robotlegs is creating for me (this object will need to manipulate the view using data from the mediator). That feels rather messy and as such is something I’d rather avoid. And anyway, I am comfortable with my mediators the way they are. They don’t get too long or complex, and they have one responsibility – to mediate between the view and the event bus. That this involves more than just catching events and passing them on, and rather involves unpacking the event and translating it for the view, and creating and packaging events to be added onto the event bus, is not a problem for me.

        Thank you for the interesting posts. This is not the first I’ve read, just the first I’ve responded to.

        • http://joelhooks.com Joel

          I favor composition over inheritance myself, but when I am dealing with MXML view I do not technically consider the markup to be inheritance in the strictest set of terms. Rather I prefer to do proper Flex component development within a base class that is “extended” in markup to manage layout and other hierarchical stuff that MXML is excellent at.

          If we use mediators in this fashion, offloading our presentation logic to them and giving them the opportunity to manipulate their views in that fashion, it seems like we are offloading significant responsibilities onto them. Putting some “ands” in the description of what they do.

          Why are we not taking that responsibility away from the mediator AND the view and placing it in a presentation model? The mediator is a switchboard. A router that delivers messages and facilitates the coordination of interests that belong to the view. It *is* a controller to coordinate bits localized to the scope of the component that it mediates. Are these patterns/classes mutually exclusive? Do we avoid the use of both simply to reduce the number of files on disk?

          I think the approach of the PM, to remove the logical bits from a view component is fantastic. I think using mediators to route messaging for components is great. How can they live together to provide a highly testable best of both worlds situation?

          Sometimes I just write components like AS3/Flex components and disregard the app tier altogether.

          • http://www.xxcoder.net Stray

            I think PM is what as3 most naturally delivers – or am I misunderstanding what it means?

            It’s those ‘ands’ in the description that really bother me :)

            I think I treat all views as components in most senses. They have to be viable and pass all their tests without the application or framework present. The mediator then just hooks events, signals and api together.

            Maybe there needs to be a version of the mediator robotlegs approach that make the 3 layer situation easier?

        • http://www.xxcoder.net Stray

          Thanks Richard – what bothers me about mixing mediator and view logic is how you can reuse that view and the view logic outside of this particular application?

          My mediators are often mediating events which are unique to this app, but the view logic is transferrable between applications.

          I think what differs between AS3 and MXML is that with MXML clearly the thing landing on the stage is harder to adjust. In my case there is usually a passive skin (assets from a swf made in flash), which is attached inside the ‘view’. But this view is still what lands on the stage – not the assets. Am I right in understanding the fundamental difference here?

          If I do, then by default AS3 allows you a view-controller approach plus the mediator on top.

          I guess you must manage reusability by having the view dictate the events in the view’s mediator, rather than the application?

  • http://nodename.com Alan Shaw

    I can’t say I follow everything that’s been said here, especially about the Presentation Model, but my practice is to try to ensure that the View knows nothing at all about the model, VOs, or framework-level logic and events, and presents a display API to the mediator. So for instance it’s certainly none of the View’s business what “user’s age under 30″ or even “user” might mean. I believe I agree with you Stray that that is app-level logic. I don’t even like sub-component ids in the view that betray knowledge of the app domain.

  • Dallin

    Ok, I’m a little confused. I can see your logic here, but what I don’t understand from your example is, if you don’t put this logic in the Mediator, where do you put it? For example, do you determine whether to show a Kindergarten Layout in the model then and then have two separate events depending on whether it is one or not? I mean, to me, a model is for data storage, state and manipulation, not deciding how to display the view. Would this instead go directly in the view then?

  • Pingback: bulupe » Great article on Robotlegs Mediator – View relation