garann means > totes profesh

a defunct web development blog

model-view-controller and roomy clothes

Tue, 10 Aug 2010 02:50:21 +0000

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.