Thunderdome MVC- Why one-model-in in MVC?
Asked Answered
H

3

8

When Jeremy & Chad posted about their FubuMvc project, one of the differentiators they mentioned was their "Thunderdome Principal":

The “Thunderdome Principle” – All Controller methods take in one ViewModel object (or zero objects in some cases) and return a single ViewModel object (one object enters, one object leaves). The Controller classes will NEVER be directly exposed to anything related to HttpContext. Nothing makes me cry like seeing people trying to write tests that mock or stub that new IHttpContextWrapper interface. Likewise, Controller methods do not return ViewResult objects and are generally decoupled from all MVC infrastructure. We adopted this strategy very early on as a way to make Controller testing simpler mechanically. It’s definitely achieved that goal, but it’s also made the Controller code very streamlined and easy to read. We’ll explain how this works at KaizenConf.

What is the advantage of their 'one ViewModel (or zero) in' approach?

Hypotonic answered 5/2, 2009 at 22:44 Comment(0)
Z
9

Its primary benefit is that it's a convention and makes things consistent across all our controllers. It makes it easier for us to set up testing "contexts"/fixtures that can initialize the environment in an integration testing scenario. In most cases, Conventions == Rapidity as it removes a lot of "what if" scenarios from your design considerations.

Since all our controller actions follow the same pattern, we can assume many things and it accelerates and streamlines our controller integrated testing efforts.

There's nothing wrong, necessarily, with having multiple arguments to a controller action, but we found that having an actual model object affords us some extra functionality since the model can contain simple logic and expose convenience properties which can simply some of the more complex aspects of its own state, etc -- basically, this is the argument for having any rich model and isn't unique to the Thunderdome/OMIOMO pattern.

Zany answered 6/2, 2009 at 16:12 Comment(6)
Okay, I can definitely buy the benefits of it just being a convention. I'll give this model a shot on one of my upcoming projects.Hypotonic
Having 16 parameters to all controllers is also a convention. Convention by itself is not necessarily a good thing.Thirtythree
@liamclennan That's correct. Smart conventions might be a better way of describing it. Fortunately, no one was advocating dumb conventions, but thank you for pointing that out :)Zany
@Zany I was not being pedantic. Your first paragraph says that Thunderdome is good because its a convention. I was pointing out that it is not a valid argument.Thirtythree
Yes, you are being pedantic. I'm not saying it's good simply because it's a convention, I'm saying it's good because it's a GOOD convention. Pedantry. Everyone knows that you can be conventionally good or bad. This is a good convention and things that use OMIOMO are good because of it.Zany
@Thirtythree - being pedantic in the course of denying your prior pedantry is not a valid argument.Accede
L
0

The advantage is that you don't rely on any sort of context (like session state, for example) from outside the controller methods. That makes it easier to test them, as you don't have to "simulate" that context using mocks, but it also makes it less practical as you have to pass everything by parameters.

Lemniscate answered 5/2, 2009 at 23:25 Comment(6)
I certainly understand that having to mock contexts and such when testing your controller is a pain - but I think that kind of pain can be eased using DI. I still don't see how having every action take a single parameter helps. Aren't you then offloading the same testing concerns to the model?Hypotonic
I don't consider having 'one ViewModel (or zero) in' means that you can only have one parameter. I think that you can have two, or even more. My interpretation is that the Action method doesn't take anything from outside the Controller class, like Http context. That's how I read it.Lemniscate
@Dave: No, the intention with Thunderdome/OMIOMO is to have one or zero input arguments to the method where the one argument is a rich model (instead of a primitive) which represents the action request richlyZany
One other thing: And that model should not be an entity from the primary domain model.Zany
What's the difference? That object follows the same pattern as the EventArgs object that contains all the event arguments in a single object.Lemniscate
@Dave: Maybe we're saying the same thing then? Having 0..1 argument to the method is important, I believe. On that 1 argument (in-model) you can have a bunch of other stuff gathered from querystring, URL, session, form post, etcZany
T
0

The benefit of the thunderdome principle is that it simplifies the controllers. Because the work of mapping http values to objects is done outside of the controllers it means that the controllers only do what they should.

Thirtythree answered 6/2, 2009 at 4:25 Comment(4)
Modelbinders map the http values to action parameters outside the controller, no?Hypotonic
I really don't think it simplifies your design. It probably simplifies the controllers, but you'll need to process it somewhere.Lemniscate
Troy is right that Modelbinders will do the lifting for you, but they can't necessarily handle some situations where logic might be required. This usually falls to the controller. With Thunderdome/OMIOMO it's in the input modelZany
@Dave Van den Eynde I simplifies the design because it allows the controllers to have a single responsibility.Thirtythree

© 2022 - 2024 — McMap. All rights reserved.