Build your own CAB Part #3 – The Supervising Controller Pattern

When last we left D’Artagnan he had just concluded a successful duel with a number of screen concerns by dividing them with a masterful usage of the Humble Dialog Box. As D’Artagnan strives to regain his breathe, he’s heartened by the appearance of his three doughty companions Athos, Aramis, and Porthos. As the four friends sit down in a shady spot besides the road for a fine meal of delicacies (unknowingly donated by a noblewoman of Athos’ acquaintance), D’Artagnan describes their predicament when they manage to corner the Lady de Winter and her host of minions.

A Shipping Screen

Let’s imagine that you need to build a little screen to allow a user to configure the shipping options for some sort of electronic order that looks something like this screenshot below:

The user first needs to select the state or province (since this was for a talk in Canada, I thought it would be nice to let our Canuck neighbors to the north use the app too) that is the destination of the shipment. Not every shipping vendor can ship to every destination, so we should modify the contents of the shipping vendor dropdown to reflect the destination. Likewise, a change in the selected shipping vendor will also cascade down to the list of shipping options (think Overnight, 2 business day, parcel, etc.). Some, but not all, shipping options allow the customer to purchase insurance in case of loss or require a signature at the destination for guaranteed delivery. Finally, the cost of the shipment should be recalculated and displayed on the screen anytime the shipping selections are changed.

I can spot a couple different responsibilities in just that paragraph, plus a couple more down the line when it’s time to actually submit the shipment. Even this little screen has enough complexity in it that I wouldn’t want to bundle all of the responsibilities into a single autonomous view. So let’s enumerate just the responsibilities from that paragraph and start thinking about how to assign these responsibilities to different classes.

Display and capture the currently selected shipment options

Respond to user events like selecting a value in the ComboBox’s

Fetching the list of states

Fetching the list of shipping vendors for a given state or province

Fetching the list of options for a given state/province and vendor

Changing the dropdown lists

Enabling and disabling the checkbox’s for purchasing insurance and requiring a signature

Calculate the shipping cost for the selected options

Update the cost textbox whenever the shipment options change

That’s a fair amount of behavior and business logic for one little screen. We know that we probably want to employ some sort of Humble View approach to split out some of the responsibilities from the Form class and into POCO classes that are easier to test. I’m going to show three sample solutions of the shipping screen, each using a bit different approach to assigning responsibilities.

Interlude

The four friends mull over the looming fight with the forces of Lady de Winter as they finish off a fine cheese produced from the endless saddlebags of Aramis’s manservant. D’Artagnan poses this question to the older musketeers: “When I’m beset by a multitude of concerns in a single screen, what technique should I use to best each concern in turn?” The three older musketeers ponder the question raised by their younger companion. Finally, Athos speaks up. “I would not concern myself with the simpler responsibilities of a screen. I would first seek to eliminate the more complicated screen responsibilities by employing…”

The Supervising Controller

The goal of the Supervising Controller variant of Model View Presenter is to remove the more complicated screen scenarios that deserve more unit testing attention out of the view and into a separate Presenter class. The Supervising Controller strategy takes advantage of the data binding support in WinForms for simple screen synchronization. To that end, we’ll create a simple class called Shipment that will be our Model in the MVP triad.

publicclassShipment : INotifyPropertyChanged

{

privatestring _stateOrProvince;

privatestring _vendor;

privatestring _shippingOption;

privatebool _purchaseInsurance;

privatebool _requireSignature;

privatedouble _cost;

publicstring StateOrProvince

{

get { return _stateOrProvince; }

set

{

_stateOrProvince = value;

fireChanged(“StateOrProvince”);

}

}

publicstring Vendor

{

get { return _vendor; }

set

{

_vendor = value;

fireChanged(“Vendor”);

}

}

// And the rest of the properties…

}

The View itself simply has a setter that takes in a Shipment object and starts up the data binding.

publicShipment Shipment

{

set

{

// start up the data binding stuff

}

}

I’ll talk about options for the Model in depth in a later post, but for now, let’s say that Shipment is just a dumb batch of getters and setters. Since I can’t stand writing INotifyPropertyChanged interface implementations by hand, you’ll probably want to codegen these Model classes — again giving me even more reasons to keep the Shipment class dumb.

We’ve taken care of the actual presentation of the shipment data, so let’s move on to more responsibilities. There’s no possible way that a screen should know how to calculate the shipping costs, and probably shouldn’t know how to fetch the data for the dropdown selections. Deciding whether or not a shipper and shipping option allows a user to purchase insurance or require a signature on receipt is business logic for the real domain logic classes, not screen logic that belongs in the screen. Let’s not particularly worry about how this stuff is implemented right now. Let’s just define an interface for all of this functionality (and a Data Transfer Object as well).

publicclassDeliveryOptions

{

privatebool _purchaseInsuranceEnabled;

privatebool _requireSignatureEnabled;

publicbool PurchaseInsuranceEnabled

{

get { return _purchaseInsuranceEnabled; }

set { _purchaseInsuranceEnabled = value; }

}

publicbool RequireSignatureEnabled

{

get { return _requireSignatureEnabled; }

set { _requireSignatureEnabled = value; }

}

}

publicinterfaceIShippingService

{

string[] GetLocations();

string[] GetShippingVendorsForLocation(string location);

string[] GetShippingOptions(Shipment shipment);

void CalculateCost(Shipment shipment);

DeliveryOptions GetDeliveryOptions(Shipment shipment);

}

The IShippingService interface works on our Shipment class that we’re binding to in the actual screen, as opposed to exposing primitive arguments. When I was writing the sample code it seemed to me to be a simple way of interacting with the service because it cuts down on any data transformations between screen and service. The CalculateCost(Shipment) method would also write the cost back to the Shipment object, cascading a corresponding change to the screen as the data binding updates the screen based on changes to Shipment. It’s probably worth noting that this IShippingService could just be a Facade class over the business logic specifically created for easier consumption by the user interface. In the next chapter I’ll take a different approach that exposes the underlying Domain Model classes for the shipping system.

At this point we’re largely left with just responsibilities for changing the dropdown options and mediating between the View and the IShippingService. That’s where the ShippingScreenPresenter finally comes in to provide the missing functionality that goes beyond simple data binding, as well as coordinating user actions with the IShippingService.

Since I’ve been claiming that this style of user interface structure improves the testability of the screen as a whole, let’s take a look at what the unit tests might look like. Here’s the unit test for correctly enabling or disabling the insurance and signature checkbox’s on the shipping screen after the shipping option changes:

The first thing you might notice is that this is definitely an interaction based unit test. That’s not surprising since one of the primary duties of a Presenter is to mediate between the services and view. In development with Test Driven Development / Behavior Driven Development, it’s often advantageous to separate the responsibility for performing an action away from the decision to perform that action. In this case, the real View enables the insurance and signature checkboxes when the Supervising Presenter tells it to enable or disable the checkboxes. In other words, the Supervising Presenter is the mostly immobile queen bee, and the View is the mobile, but relatively brainless, worker bee. In unit tests like the one above, we’re largely testing that the Presenter is sending the correct signals to the View and service interfaces.

For another example, here’s a unit test for recalculating the shipment cost as the selected shipping options change:

That wasn’t that bad, now was it? But wait, you ask. Where’s the actual logic for calculating the shipment cost? For right now I’m just worried about the wiring of the screen itself. Yes, this unit test covers very little ground, and it’s not a “real” test, but I’ve created some level of trust that this particular linkage in the code does work. I can now turn my back on the screen itself and test the actual ShippingService by simply pushing in Shipment objects and checking that the Cost field is correctly updated. Not one single line of the shipping screen code needs to be present for any of that logic to be tested. I hope it’s needless to say that there really shouldn’t be any leakage of domain logic into the screen code. Real domain logic in views is just about the fastest way possible to create an utterly unmaintainable system.

Interlude

The four friends pondered Athos’s solution in quiet contemplation in the state of contentment that only follows a fine meal. “Wait,” exclaims D’Artagnan, “You haven’t told us how the View talks to the Presenter, and who creates who! How should this work?” Athos simply shakes his head and says “it’s a long ride to Dunkirk, we’ll talk more of this on the road.” (as in, I’ll get there, just give me a couple more chapters – Jeremy).

How I Prefer to Work

Personally, I wouldn’t order the work quite the way I showed above. I like to start with either a screen mockup or maybe even the actual view. If you start with the actual concrete view class, don’t wire it up yet, and whatever you do, don’t automatically implement the intended “IView” interface until you’re done with the Presenter. Sometimes I’ll start by taking some notes or sketching out some UML or CRC models about the screen scenarios. My next step is to encode the behavioral aspect of the screen in the Presenter. I use RhinoMocks in place of both the View and whatever service interfaces the Presenter needs. As much as possible, I like to define the methods and interactions of the Presenter with the services and view in a unit test body and just let ReSharper generate the methods on the dependencies. Since we’re strictly dealing with interfaces here, we don’t have to break our flow with the Presenter to implement the services and view just yet. As soon as the Presenter itself is fully fleshed out, I implement the IView interface on the real View and create an implementation for any of the service dependencies.

This probably isn’t realistic for complex screens, but at least on simple screens it should become quite ordinary for a screen to just work the first time it’s run in the UI — assuming you unit tested all of the pieces individually.

Summary

I’d bet that Supervising Controller is probably the most commonly used Humble View architecture, but I don’t have any figures at hand on that. It still allows you to use the design time support to layout controls and even configure the data binding with the visual tools (but we’re going to talk about options to data binding later). My current project is using Supervising Controller (sans data binding), and I think it’s largely where the sweet spot is. I will use the other options at times though, and there are a lot of different variations on each of the other Humble Views, so we’re not done yet.

Is this really worth doing? I say yes, otherwise I wouldn’t be doing it. Let me put it to you this way, on the first project I used the Humble View (Passive View actually) approach, we saw a strong correlation between the bug count per screen and the unit test coverage for the code on that screen. Screens that were driven with unit tests on the Presenter had many fewer behavioral bugs. I’m talking it even farther on my current project by adding NUnitForms tests on the View to Presenter interaction, plus Fit tests on the actual screen behavior.

If you’re not a fan of interaction based testing, and using mock objects gives you an allergic reaction, don’t worry. I’ve got stuff for you too coming up.

Conclusion

The four friends pondered the wisdom of Athos’ approach while drinking their way through the rest of the wine from D’Artagnan’s packs. Suddenly, mighty Porthos clears his throat and…

To be continued in Part #3 – The Passive View Pattern

About Jeremy Miller

Jeremy is the Chief Software Architect at Dovetail Software, the coolest ISV in Austin. Jeremy began his IT career writing "Shadow IT" applications to automate his engineering documentation, then wandered into software development because it looked like more fun. Jeremy is the author of the open source StructureMap tool for Dependency Injection with .Net, StoryTeller for supercharged acceptance testing in .Net, and one of the principal developers behind FubuMVC. Jeremy's thoughts on all things software can be found at The Shade Tree Developer at http://codebetter.com/jeremymiller.

“So if I want to use 2-way data binding in a supervising controller, should I be prepared for angry people, saying that my take on the pattern is wrong?”

It’s partially a case of “who cares what other people think”

In your case, I think you want to look at the Presentation Model pattern instead (the WPF team calls it Model – View – ViewModel). PM is ideal for this kind of state machine screen thing you have.

Miksu

Hi.

First of all, thank you for great posts. Hopefully someday you’ll finish this series but in the mean time, the already available posts contain great deal of interesting information

I have a question about the supervising controller pattern. All the examples I’ve seen show the data binding between the view and the model as a read-only (1-way). What’s your opinion on using 2-way connections between the view and the model? I’m creating a WPF application and it seems kind of pointless to direct all the user actions first to then presenter when I could talk directly to the model.

For example, I have a CustomerEditView. It contains about 10 textboxes where the user can write related information. In addition to that, the view has few buttons (delete customer, update customer, cancel). If I want to show interactive information when user is changing the data (for example “Name is too short”), with the 1-way connection I kinda have to implement “Changed”-methods into the presenter for every available textbox. I then end up with methods like FirstNameChanged, LastNameChanged, AgeChanged etc. etc. These methods are called by the view when for example FirstNameTextBox changes. This method then changes the value in the model and may present an error to the user if the new value isn’t valid. Writing these feels really cumbersome.

So how about using 2-way data binding? This way I could delete all the Changed-methods from my presenter and just let the data binding provided by WPF to handle this stuff. Presenter would only contain the more complicated stuff, which in my case would be the handling of update, delete and cancel actions.

So if I want to use 2-way data binding in a supervising controller, should I be prepared for angry people, saying that my take on the pattern is wrong?

Best regards,
Mikael

http://www.illede.net rüya tabiri

Thank you…

Sunny

Hi Jeremy, I was reading the code and I just wonder if you might have missed the code to set the Locations in the view (or I have mis-read it)? and if so, am I right that it should be after setting the Shipment in the _view (at the end of the Start method)?

http://codebetter.com/blogs/jeremy.miller Jeremy D. Miller

@Kent,

That sounds cool. This is one of those scenarios where I’d like to play with compile time IL weaving to layer the extra stuff on sometime.

http://kentb.blogspot.com Kent Boogaart

Thanks Jeremy. I see what you were getting at now.

> You could beat it all with codegen, but I really don’t want to have to codegen my domain model classes because I think that’s a drag on productivity

I concur, which is why I put together a home-grown codegen solution in past projects which has saved me a *heap* of time. I have formalised this solution and am planning to release it soon on CodePlex.

It’s basically codegen built right into VS. You change your template or input file, hit Ctrl-Shift-B and it’s done. It assumes nothing about input format or template engine (comes with NVelocity support). The core of the product is done. The only thing I have left to do is add VS integration to avoid the need for manually editing project files.

Anyways, basically what I do is define a simple input file that defines each of my domain objects. Then I have an NVelocity template used to generate a partial class for each domain object. Works a treat. Not only can you do stuff like change notification easily, you can also do stuff like generate custom serialization logic (ie. implement ISerializable) to keep your domain serializing like a ninja, implement IEditableObject etcetera etcetera. And all without sacrificing maintainability or productivity.

http://codebetter.com/blogs/jeremy.miller Jeremy D. Miller

@Kent,

All I meant was that in real life I do not use INotifyPropertyChanged. I did in this example, and the naive implementation is partially because I don’t actually use it on projects.

“And I’m curious as to why implementing INotifyPropertyChanged in your domain layer would be a bad thing. I typically have my domain layer support change notification so that binding directly to domain objects is possible. Makes things much easier, IMHO.”

This is funny, I’m having this exact same argument with Ward Bell at the moment. My point of view is that INotifyPropertyChanged/IEditableObject/IErrorInfo and what else is noise code that detracts from the readability of my domain classes. That stuff is infrastructure concerns that shouldn’t show up in a domain model class. It’s also modifiability to me as well. Modifying or adding a property, then tweaking the INotifyPropertyChanged implementation is friction to me. You could beat it all with codegen, but I really don’t want to have to codegen my domain model classes because I think that’s a drag on productivity.

I might happily use INotifyPropertyChanged if I was using codegen’d DTO’s for the Model.

I’m well aware that I’m the unusual one in the .Net world on this topic. I’m bypassing data binding altogether in favor of my own MicroController strategy, and it’s going smoother than my prior experiences with data binding.

I do cover a bit of this stuff in the section on “What’s the Model?”

http://kentb.blogspot.com Kent Boogaart

@Jeremy

*confused* Your example already has a Shipment class that implements INotifyPropertyChanged. What I’m saying is that if you alter the implementation of Shipment to correctly honor the contract, you will avoid this problem without need of a latch.

And I’m curious as to why implementing INotifyPropertyChanged in your domain layer would be a bad thing. I typically have my domain layer support change notification so that binding directly to domain objects is possible. Makes things much easier, IMHO.

http://codebetter.com/blogs/jeremy.miller Jeremy D. Miller

@Kent,

But then I’d have to use INotifyPropertyChanged on my domain classes;-) I’m perfectly willing to tilt the windmill and build my own screen synchronization that binds to POCO’s instead.

The MicroControllers thing I use in place of data binding takes care of the latching for me. OnChange events will not fire when the binding is being updated.

http://kentb.blogspot.com Kent Boogaart

Another way to fix the circular/recursive event problem is to properly honor the contract of the INotifyPropertyChanged interface. The PropertyChanged event should only be raised if the property actually changes:

Just another class. All I wanted to show was a separation of concerns for the shipping logic and data access from the Presenter. In my systems IShippingService would be attached with an Inversion of Control tool (StructureMap).

ShawnD

What class implements the IShippingService?

http://codebetter.com/blogs/jeremy.miller Jeremy D. Miller

@Max,

Nice catch! This isn’t real code from a working app (obviously). Yes it certainly would create a circular event. I use pretty well exactly what you describe in these cases where an event causes an action which potentially raises the exact same event. There’s a pattern from messaging called the “Latch” that’s basically what you describe. I don’t necessarily have anything better. I’m including a little bit about that in the post on the Event Aggregator.

Of course, in this case you could beat it by removing Cost from the Model and pushing in the updated Cost through more of a Passive View approach.

http://bloggablea.wordpress.com Max

I’d like to add my own voice to the many above congratulating you on this series :-).

However, am I right in thinking that there is a slight bug in the code above in that changing ShippingScreenPresenter._shipment.Cost results in a call to _shipment_PropertyChanged, which calls IShippingService.CalculateCost(_shipment), which updates the Cost of that shipment, which results in a call to _shipment_PropertyChanged…..

I’ve hit this kind of circular update loop a few times in my own apps, do you know of a clean workaround? My solutions in the past have involved defining a sort of transaction in which updates to the event triggering model object are done, and events to actually be fired are queued up until the transaction commits. If a change to a model property happens when a transaction is already on progress on the model, I don’t raise the event. I’m not sure if this is the best solution however… would be interested in hearing your thoughts.

Jeremy Wiebe

I’ll second all the comments about these being useful posts! We’re just now heading down the path of evaluating the Web Client Software Factory. Our reasoning for evaluating it is that it forces us down the path of the patterns and does some hand-holding in applying those patterns because many of us are not very familiar with the patterns (yes, we’re learning them but there’s only so many hours in a day). The other compelling reason is that the WCSF uses WF (Workflow Foundation) for the page navigation and that brings some really nice benefits in terms of the user being able to abort a “process” and return to that exact point as if they never left. I’m not sure how you’d build that, but just thinking about it does not seem like a simple task to grow yourself. (I’d compare that to a build vs. buy decision).

Oh, and hurray for having “State or Province”! I’m one of those crazy Canucks!

http://mc.freezope.org/ Matthias Cavigelli

Thank you for the realistic example. The dependent dropdown lists are a common example of how business logic and complexity infiltrate the view.

It’s also interesting to see where you divide between Winforms Databinding and custom code.

I’m looking forward to your post on Passive View.

Steve

These posts are greatly appreciated, thanks for providing this to community.

I’m using MVP right now and every tidbit helps. ie. I’m not using the INotifyPropertyChanged right now, and I’m trying to wrap my head around how I can implement this (I’m using a webform though, so not sure about the difference here)

http://www.e-Crescendo.com jdn

Cool. When I’m trying to really learn something, I tend to focus on every difference.

Great series BTW. I’ve been reading everything about MVP I can get my hands on, and this really helps things come together.

This is probably a silly question, but is there a specific reason why in the tests you call the view a screen and not a view?

Couldn’t more complicated screens implement multiple views?

Wondering if there was a prescriptive (or other) reason for the terminological choice, or if that is just what you typed (so to speak).

http://codebetter.com/blogs/jeremy.miller Jeremy D. Miller

@Nate,

Let’s see,

“SmartPart” — right there I’m already shaking my head at CAB nomenclature. I’ll read up on it a bit and see if I think it’s worth showing something

Dependency Injection — Lot’s of people are asking for this, and I think I made some disparaging remarks in the past about ObjectBuilder, so I’ll definitely show what StructureMap can do instead.

Loose-coupled messages — I’ve got an example of an Event Aggregator

http://kohari.org/ Nate Kohari

This is a great series of posts! I’m a big fan of MVP via Passive View, and I’ve used it extensively, but it’s helpful to read another take on it. I’m interested how far into the CAB you’re going to delve — SmartParts? Extension points? Dependency injection? Loose-coupled messages?