model-view-controller and roomy clothes

It finally happened. .NET MVC and I came to blows, and are no longer speaking. This is super awkward, as we still have to work together. And, you know, part of me thinks it’s possible that I’m not being entirely fair, that I’m judging .NET MVC solely on the way it’s behaving right now and it actually has more to offer and we might even be able to get along, were circumstances different. Another part of me thinks that they’re not different and I am tired of .NET MVC’s bullshit, situational or otherwise.

The further I move away from backend development, the more I find myself wanting to use Javascript on the serverside. In this specific case, my reasons are simple and selfish: I want dynamically typed objects. Whether it’s an innate property of the framework or not I don’t know, but .NET MVC seems to be built around the idea of a one-to-one relationship between data objects and the pages that display them. As I’m seeing it used right now, it would be very good for some WinForms desktop app where every new screen represents a single table in the database, but it is just shit for webpages that pull little bits of various models in from all over the place and try to offer functionality spread across different controllers. My thinking is that if a View can truly be said to need to know nothing about the Model that hydrates it, the developer working on the View should not have to be intimately familiar with the Model to do her job. Nor should she have to wait for a backend guy to free up in order to get some data added to the object used by the page she’s working on. Data should be provided by the Controller and the View should be able to grab what it needs without an act of god.

Yeah, I know, the View should be dumb. Eff that. This is 2010, this is the web, and the View is pretty much the application. To say one page must commit itself to one server-defined type of data and cannot go out and forage through the controller for other information it needs is just.. nuts. I don’t see how Model-View-Controller can work on complex, interaction-heavy websites without a little more flexibility in its definition.

The utility I see in the MVC pattern is in separating frontend logic from backend logic, in enforcing loose coupling. The View and Model should both interact with the Controller, totally agree with that. I think pretty much everybody does. Where opinions and definitions begin to diverge, I think, is in how much control the View and Model themselves have over their own domains. As far as I’m concerned, it should be limitless. The Controller’s job on the GET is to package the data, to expose useful helper methods that do things like loop through the customer’s history to find out which songs she’s already favorited or which books she’s purchased. On the POST, its job is to double-check the View’s validation and return an error if the customer tried to order a band saw that just sold out.

The biggest issue I have with .NET MVC as I’m seeing it used is that the controllers do not write helper methods. Their methods either provide or receive entire pages, and I don’t see the value in a one-to-one relationship between methods and pages. There are some “HtmlHelpers”, but these provide actual markup and I don’t think that’s any of the backend’s goddamned business. The issue I have with MVC as I’ve seen it applied to a variety of languages is the notion that a Controller should be in charge of serving pages. Horseshit. The View should be in charge of serving pages. It knows more about them and more about the client consuming them.

I don’t know if this makes me a lunatic or what. I do know that prior to .NET MVC, me and a woman I worked with wrote our own MVC in .NET using this basic philosophy and it seemed to work fine. It was well organized, loosely coupled, and flexible enough that I didn’t spend entire workdays wanting to throw things.

..Which kind of leads into a related topic: something very interesting Rebecca Murphey posted today on jQuery in large applications. It got me thinking, because I both agree and disagree. I think it’s important that people’s skills progress beyond simple DOM manipulation, but I find the idea of an all-in-one solution for large applications difficult to swallow, perhaps because of the experiences I’ve had with those sorts of setups in backend languages. Yes, they promote better coding practices and provide structure and predictability. But my personal experience has been that there’s a trade-off in terms of flexibility.

I worked with YUI for a while and it left me with a preference for jQuery. Not for very complex reasons – I just felt that the things I wanted to use most, functions for building objects and wiring up events, were exactly as difficult to get to as the things I never used, the wide variety of widgets YUI contains. Additionally, I had problems with many of the widgets. They were all very nice and pretty reliable, but when I tried to push them beyond the examples given in the documentation, I was getting about a 50% success rate (again, I was using very few of the widgets, so grain of salt, please). This is why I ended up rewriting the last application I worked on in jQuery, doing exactly the thing described in the post: piecing together a custom cocktail of templates and patterns to suit my own needs. At the risk of disagreeing with very smart people, I thought this was awesome. I had what I needed, nothing I didn’t, and the setup lent itself very well to roll-your-own solutions.

It may seem I’m intentionally missing the point, but I do understand the problem with roll-your-own solutions. I do agree that it benefits everyone to be working in the same setup and making use of tools that have been vetted by geniuses whose entire job is to create such things. But I’m dubious about any approach which comes too close to promising one size fits all. If you’ve ever sewn a dress, you understand that one size fits all is technically possible, but some people are going be left with a lot of excess while others will scarcely be able to breathe.

Frequently when we talk about architectures, we talk about the ability to scale, and we mean scale larger. I don’t think enough thought goes into scaling smaller. If I could have stripped down YUI on my old project, made the nuts and bolts more accessible while getting rid of the tile saws and routers, I would have done that. But it took less time to just rewrite the damned thing in jQuery, and left a more maintainable product. I’m not sure it’s possible to scale smaller. With that in mind, I think it’s best to start with the most nimble tool that can do the job.

I guess this is still more about .NET than it is about Javascript, though it’s the reason some of what Ms. Murphey is advocating makes me nervous. If we’d done what we’re doing at work right now with ugly, messy, oldschool code-behind pages I think we’d have a better codebase. I think we could have gotten all the benefits of MVC without the branding, I think the frontend people would be less reliant on the backend people, I think we’d be able to make changes more quickly, and I think we’d be a hell of a lot better off. In every language there are patterns and frameworks that promise a better, cleaner, more comprehensive way of doing things, and that no doubt will deliver, assuming what you want to produce is what they’re meant for. But if you try to get them to produce something different, all they deliver is a bigger mess.

In conclusion, consider the bespoke suit. The quality is less reliable than something made in a factory by perfectly calibrated machines. No groups of fashion experts have gone over its every detail to make sure each is the best it can be. You cannot get a new one exactly like it, only in navy. If your tailor retires, anyone else you let touch it is probably going to ruin it. But you know what? The motherfucker fits.

Tags: , ,

8 Responses to “model-view-controller and roomy clothes”

  1. Rebecca Murphey Says:

    First, please keep writing. I am really enjoying it. Second, I’m going to use your comment section to try to articulate a thing that I hope to eventually write about at greater length on my own blog. I hope you don’t mind.

    I think there’s a distinction that has to be made between a one-size-fits all solution (and while I don’t know squat about .NET MVC, I do not doubt your assessment of it as such) and a toolbox that provides tools to do all sorts of things, rather than asking you to assemble those tools yourself.

    My personal preference, of late, has been to use Dojo, not because it purports to solve every problem or prescribes how to solve them, but because it gives me so many tools to use to solve a given problem. Time and again I find that “Dojo already did that” — they already wrote the tool I’m wishing I had. Now I don’t have to write it, and, perhaps more importantly, I know it was written to work with all the pieces I’m already using, and when I use it I’m not risking duplication of code or a lack of testing, maintenance or support. Win.

    But let’s be very clear: no one’s forcing me to use that component! I can write my own if I want, or use someone else’s if I want, or change it a bit if I want! For example, on a current project I pulled in mustache.js because it’s pleasant and because a lot of templates for the project had already been written using it. The brilliant thing, though, was that integrating mustache.js into dijit._Templated instead of the standard templating system was trivial. That component, and so many others, are architected with exactly the flexibility you talk about in mind, while providing a rock-solid base for application development.

    Revisiting your metaphorical dress, these pieces are starter patterns, not finished one-size-fits-nobody garments. If you’re smart you’ll take some measurements and make adjustments along the way for a perfect fit. jQuery in large applications, to me, can feel like I’ve been given a black marker and some of that crinkly brown paper, and now it’s up to me to draw a pattern. Intellectually interesting, sure, but not my cup of tea.

    Working with an “integrated” toolkit like this works better for me than assembling my own toolkit to answer low-level application architecture questions like dependency management, inheritance, communication between components, data abstractions, etc. — at the end of the day, I trust the collective wisdom of really smart people who have thought about these questions over the course of years more than I trust my ability, as a mere and fallible individual, to think through the problems and come up with the right solution.

    But! I do not begrudge people who come to a different conclusion, and choose to roll their own solution. What’s important — what’s imperative — is that if a developer chooses to do so, they understand that the questions may be bigger than what jQuery was ever intended to answer. If we can all agree at least on that part, then we’re already headed to a better place.

  2. brad dunbar Says:

    Love this post, love Rebecca’s post, and I’m certain the correct approach lies somewhere between them. I also use asp.net MVC in my day job and long the the nimbleness of python. I have no idea which is better, only which one makes me feel comfortable.

  3. garann Says:

    @Rebecca – I feel silly finally responding to this now that you posted your extended thoughts on the topic on your own blog.. So I’ll just be real brief. :) The part that gets me is when what comes with the toolkit doesn’t quite do what you want. As you mentioned, of course you can just adopt something else, but personally I always feel a little dirty doing that. Like, if I’ve committed to a framework, I should stay within it or I begin to lose the true benefit of the framework. This problem came up with the YUI text editor, and until I rewrote the app with jQuery, I was (subtly) changing the way the app worked to accommodate YUI’s editor. And the same issue is occurring with .NET MVC on my current project, but in much more distressing ways. That’s my big fear – having to change the design or architecture of an application to fit into a framework.

    @brad – I feel you. Although I think it’s obvious which is “better”. I just think the one that’s “worse” is frequently the more practical. :)

  4. Avi pinto Says:

    great post, really liked the “The further I move away from backend development, the more I find myself wanting to use Javascript on the serverside”.

    concerning using a dojo like solution vs jQuery and lots of plugins/other components, @Rebecca’s post made me think about it as i struggled to make peace between the jQuery.validate and two other plugins :).
    i still don’t know which is the best way to go(but it made me wanna learn dojo, no time for it yet).

    for no i’m rolling my own only when i don’t find the right plugin/component(doesn’t have to be jQuery) – i just open it’s code before i use it to asses it’s quality and see how difficult it will be to make my changes(since almost every plugin needs some love) – after all it all just Javascript ;-)

    I use asp.net MVC and a lot of jQuery, and you are right that sometimes MS MVC gets on the nerve with the viewModels that you need to create to make typed views, and creating forms can be a pain.
    but you can reuse views by using interfaces/break the views into partial views.
    and concerning grabbing other data – there are several options:
    1. use RenderAction – in places that need other data inside your view – just create another action with it’s partial view and access it from your view when you render the page.
    2. for interaction in the page after it was rendered access the action you created via AJAX and get a baked partialView or raw JSON data and bind it
    3.you can always just return JSON from your views/partial views and use a template solution to build everything.

    the greatest thing with MVC is that it is really extensible, and is code is opened to the world so you can view it before extending it

    WebForms is CRAP!! – sure you can build a sort of MVC app that is driven by the view with lean code behind(did it in several projects prior MVC) , but it it not as simple and straight forward as doing it with MVC.

    keep on writing, love your blog

  5. garann Says:

    @Avi – That’s what were doing, primarily, using partial views with specific viewmodels. But that gets kind of cumbersome for very small pieces of code you want to reuse – like a thumbnail wrapped in a link or something. That’s where I’d prefer a method on the controller to just provide the necessary info as JSON.

    Hence the desire to use Javascript on the server-side. Many of the messes that were created were the result of trying not to repeat rendering logic (which I don’t think should be as high a priority as repeating backend logic, but that’s a different topic). If rendering logic could have come from the same place for server-rendered and client-rendered scenarios, it would have been much cleaner.

  6. Avi pinto Says:

    totally agree,
    it would be awesome to just use js at the server side.
    now to get rendering logic on the interfaces i use extension methods (which is also not the best solution)

  7. Asbjørn Ulsberg Says:

    “If rendering logic could have come from the same place for server-rendered and client-rendered scenarios, it would have been much cleaner.”

    The Spark View Engine is not only a great alternative to the old ASP syntax of ASP.NET MVC, it supports rendering of its markup both server and client side. Have a look at the following URLs to get an idea of how it works:

    http://odetocode.com/blogs/scott/archive/2009/03/12/client-rendering-views-with-spark-and-asp-net-mvc.aspx
    http://blog.robertgreyling.com/2010/08/elegant-mvc-with-spark-way-views-were.html
    http://blog.robertgreyling.com/2009/11/teaching-javascript-how-to-render-your.html

    Combine this with the “dynamic” type found in .NET 4 and ASP.NET MVC doesn’t have to be as bad as you’ve experienced. :)

  8. Jayfon Says:

    Love both posts (Garann’s and Rebecca’s), oh and Bob’s makes for entertaining reading too http://bobremeika.com/2011/03/03/jquery-is-for-n00bs/
    Without trying to introduce framework bias and duels into the equation, part of the issue between the posts about jQuery and Dojo and .NET MVC, is framework quality.
    One thing that I’d like to posit is that as the framework becomes larger, the quality (read flexibility, extensibility, maintainability) of the framework becomes exponentially more important. It is easier to see if a light-weight framework is going to work for you. Once you get to heavy lifting though, you have a much longer and more involved process of evaluation. It is also much harder to back out and switch to something else.
    Garann, I’m wondering if the nervousness you have about rMurphy’s suggestions has more to do with your, can I say bad, experience with .NET MVC than the arguments for adopting Dojo over jQuery for instance.
    I am currently wrestling with WPF and MVP, Linq to SQL and Entity Framework, having moved from Win forms and home grown data access. What have I got? A whole lot of trouble for little (any?) gain. Still, I like the reasons Rebecca (and Bob even) put forward for adopting Dojo over jQuery. Depends on your requirements I guess.