design patterns - Cross-component Communication within a View (MVC)

What are some best practices to orchestrate the interaction between complex components that are in your View?

I'm not talking about simple widgets like a combo box or a grid control but components that are made up of multiple widgets and that may deserve being unit tested on their own.

Would you:

  1. Define abstract interfaces for each component, let the Controller hook them up via dependency injection to let them directly talk to one another via method calls? The components are therefore aware of other components' interfaces.
  2. Define events that each component can fire and let the Controller directly hook them up via event listeners on one another? The components therefore have event handlers attached to other components' event sinks.
  3. Define abstract interfaces for each component, define events that they can fire and let the Controller listen on all events and perform method calls on the interfaces? The components therefore are completely agnostic towards other components.
  4. A classic application of the Observer pattern?
  5. Anything else?

Update: I've stroke out "let the Controller ..." from #1-3 because it's not necessarily the Controller that has to do the routing/orchestration in those cases. It could be the View itself.

I've adopted method #3 in a recent project and I was happy with the decoupling and individual testability of the components. However, I have a feeling that I could streamline the wiring up of the components. In my case, the main View object has to add multiple event listeners on each component and then call methods on appropriate components, after sometimes doing some local processing (like talking with the Model). The code for adding the event handlers looks a bit messy and I'm particularly looking for a clean way of doing that.

2 Answers

  1. kate- Reply


    Option #3 sounds like the Mediator pattern and is often the best approach when the update logic and communication between the objects is complex. It also has the added advantage of keeping the control logic and initialization centralized which tends to make tracing through and debugging these types of cases easier.

  2. Aaron- Reply


    It sounds like you have the knowledge to answer your own question on this one but maybe just lack the confidence to dive in. Are you just exploring or are you stuck somewhere?

    I would add that one extra thing you can do is place a component manager in between all of the objects to facilitate the communication. In the past when I've done something similar, the management object ended up just taking data from each component, merging the data together, and passing it along to the model as one big request. Each of my components had a delegate they would call and would pass data into and of course the implementation of that delegate was on my component manager.

    I also let that manager object act as a proxy to the network I was waiting for the complexity to get higher before I adhered to SRP and made that responsibility its own class.

    Basically everything you said sounds good. I'd recommend to just dive in and explore.

Leave a Reply

Your email address will not be published. Required fields are marked *

You can use these HTML tags and attributes <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>