Uncle Bob Martin has had a lot of influence on the software development industry over his career. His books are heralded as “landmark” and “essential tome[s].” He is credited as “legendary” (ugh) in his author biography on Amazon. I don’t doubt that he’s an incredibly smart guy from what I’ve read from him. Some of his articles are fantastic reads. But I think perhaps either I haven’t read enough to get a real impression of him, or the conference talk I recently had a chance to watch is significantly more dishonest than his writing for some reason.

I was wandering down a rabbit hole of Twitter/Hacker News discussion, and I kept seeing people linking to his keynote video from Ruby Midwest 2011 as a “very important talk to watch.” I’d sat through at least one (possibly more) of his conference talks before without paying much attention (I unfortunately often find it hard to focus on conference talks), really liked what I heard at his RailsConf 2009 keynote (missed his 2010 one), and since this particular talk was relevant to what I was reading at the time, I figured I’d give it a more attentive watch.

I realize I’m probably going to tick off a lot of people here, but what I heard was seriously troubling. (There’s that and he took time to correct everyone else’s talks at the start of his talk, so I figured turnabout is fair play. :))

I’d heard his talks described as “sermons” before, but I never realized how hand wavey they could be at times (at least this particular one). I had to watch it 3 times to get at his main point, which still (to my ears) doesn’t really have any evidence behind it or meat to it outside of “Uncle Bob says.” Even worse, as I was listening, I kept getting angrier by the minute at the gross mischaracterizations or downright mistruths he was spouting. The following list is just a collection of things I caught on my first couple of listens. Maybe there are more in there, but these were glaring enough to catch my attention.

Assertion: Architecture is about intent, and intent should be evident when looking at a software project, so the Rails directory layout sucks. (around 11:00)

He led everyone to this point by showing them blueprints of buildings, indicating that a building’s purpose should be and is evident by how it is architected. From this, he then makes the logical leap that this should absolutely be true of software, and that when you look at the top level directory of a project, the architecture should be evident, not the framework. His criticism is that when you look at a Rails application’s directories and files, you can readily see it’s a Rails application but not what the application actually does.

Disregarding the fact that having standardized file placement driven by the framework is one of the biggest wins for development teams when using a framework, that’s one of the most bizarre criticisms I have ever heard in a conference talk. I have never in my career worked on a project where I could simply glance at the file layout and discern exactly what the application does. Heck, even in things like XCode or Visual Studio, where one can have a logical layout of the files with smart groupings, I haven’t been able to do that.

The better question is: why would you need to? You’re a developer. You’re going to be building the project out, so you’ll figure out what the app does soon enough. What is more convenient for you: a gangly file layout/”architecture” that is non-standardized, annoying to navigate, and requires documentation for others to navigate or something standard that makes your locating files and important logic in those files that much easier? And even so, as his argument indicates even, file layout doesn’t speak to the functionality of the application. You could just as easily follow his suggestions but put different, unrelated code in the files, and you’d be in a worse position. It’s a foolish, silly criticism that probably sounded better on paper than when it came out in the talk.

The worst part was that at around 28:00 he advocates an alternative directory structure based on the architecture he’s describing in the talk, which has names that are just as or even more opaque: interactors, entities, and so on. He also suggests you’d have interactor files named after use cases (e.g., create_order.rb, fill_order.rb, etc.); I would personally kill myself if I had to navigate a huge project in this structure. I get the idea here, but is the ability to quickly sort of discern what an application does worth making your developer’s life a miserable existence during the other 99.9% of the project? Who would want to figure out in which of the 500 use case files that this particular piece lived in? Nobody, that’s who. This point was one part of the talk where he totally lost me in terms of what he was actually trying to say other than “I needed 5 more minutes of material and this seems like a good place to start the rest of my arguments from.”

Assertion: Views should know nothing about the business objects. (Around 32:15)

Perhaps that’s his opinion on things, but if we’re going to appeal to MVC’s origins and go by standard, accepted definitions, that assertion is just patently false according to much of the authoritative MVC documentation. For example, in the paper where the terminology is finalized for MVC dated December 10, 1979, Reenskaug writes in reference to views and how they get or update data in models:

A view is attached to its model (or model part) and gets the data necessary for the presentation from the model by asking questions. It may also update the model by sending appropriate messages. All these questions and messages have to be in the terminology of the model, the view will therefore have to know the semantics of the attributes of the model it represents. (It may, for example, ask for the model’s identifier and expect an instance of Text, it may not assume that the model is of class Text.)

In the original vision of MVC, the model, view, and controller were separated but communicative. A view can ask request data (or update a model (Heaven forbid!), an action which he derides at about 31:45) as needed for its functionality (so long as it doesn’t violate its role in the triad). Acting as if a view should be and always has been a “stupid piece of tiny code” that is simply feed flat data that it renders is false.

Assertion: You should have “hundreds” of views, not just one view. (Around 30:30)

Again, he harkens back to MVC’s roots and asserts that the Rails way of having one view (the page) is wrong, and according to the original plan, you should have hundreds of views, so MVC is a flawed model for doing things on the web. And again, he is incorrect.

Quoting from How to Use Model-View-Controller, a paper describing the original implementation of MVC in Smalltalk:

Views are designed to be nested. Most windows in fact involve at least two views, one nested inside the other. The outermost view, known as the topView is an instance of StandardSystemView or one of its subClasses.

In the original Smalltalk environments, having an overarching, top-level view for the M-V-C slice you were working with was common (and likely required in most situations). If we envision the page to be the same “object” as a window in the original implementation (which I believe is how it should be viewed), then the pattern fits quite well, especially since partials (and cells if we want to follow his assertion that all views should have an M-C piece to them) provide the same subview functionality. This fact is especially true if we get over the whole notion that the MVC pattern is a totally defined, prescribed Pattern™ that you must adhere to religiously and unwaveringly and instead take it for what it is, which is a loosely defined pattern that describes a way to reduce and manage complexity in systems (post coming about that attitude tomorrow…).

Assertion: Point of writing tests first is to avoid coverage gaps (or just about anything else he said about TDD in the talk).

A lot of his tangent into TDD starting at around 58:00 was silly. First, he asserts that writing tests after the fact is “a waste of time.” Granted, you’re more likely to miss some coverage if you do only that, but who doesn’t write quite a few tests after the implementation? Lay down a solid, basic set of tests covering what you’re writing, then go back and cover the edge cases when you have a clearer picture of the logic and its interactions with other pieces of the system. It’s stupid to act as if writing any tests after the implementation is useless.

Secondly, he asserts that the reason everyone TDD’s is to avoid coverage gaps. Now, I don’t know what sort of Magic Double Dream Hands TDD™ he’s doing, but the only “coverage” gains you’re making by TDD’ing are the kind that don’t matter (i.e., numbers not quality). That’s great that you have 100% coverage, but are your tests actually robust? And, even further, if you’re requiring 100% coverage, are you over-testing things? (If I see a unit test for the existence of an attr_accessor or a constant value one more time, I will scream) These questions don’t seem to faze him however. TDD’ing leads to perfect coverage, which, of course, means impeccable quality tests! </sarcasm>

Assertion: MVC is meant to be used in the small, so Rails does it wrong. (Around 31:30)

This was probably the most frustrating point in the whole talk. He twists and contorts MVC’s role in a Rails application and then muddles the terms of architecture pattern and design pattern to forge a point that Rails usage of MVC is inherently flawed according to how the inventor intended the pattern to be used.

Yes, as he asserts, MVC is meant to be used “in the small” in the sense that it takes one slice of your application, separates its concerns, and then lets you independently manage the complexity of those concerns. He is correct in that it is not necessarily an architecture pattern. But his diagram of how a Rails app looks versus this architecture he’s discussing in the talk is just simply disingenuous.

Not only does he conveniently rearrange the pieces so that it seems disjointed, he also completely pulls it out of the proper place in the architecture diagram to make it seem sloppier than it really is.

Even further, Rails uses MVC in the exact way that the original creator of the pattern intended it to be used. It doesn’t use MVC to handle the entire cycle of interaction in the applicatio (f.e., it doesn’t treat the web as part of the MVC mechanism). When a request comes in (i.e., user input), the input is passed to the controller, which decides what should be done with it, how models should be updated, and which views should be rendered for that particular input from a view. This is nearly exactly how it’s done in Smalltalk, exactly how it’s been done in nearly every other implementation of MVC, and this is exactly the “small” that it’s meant to be used in. It’s not being used to build the framework (i.e., your app isn’t treated as some weird model plugged into one giant MVC mechanism or something), it’s not used as the framework/application “architecture” (that’s actually something akin to a Model2 architecture pattern), and it’s not being shoved somewhere it doesn’t belong. It’s exactly where it’s supposed to be.

In reality, Rails is fairly close to the architecture he discusses. It’s not as decoupled and interface driven as he’d like it to be, but that’s the real rub with this entire talk: he’s complaining about Rails “flaws” that aren’t part of its DNA. It’s like complaining about how a sweater isn’t a very good conversationalist. He ends the talk by harping on the fact that good architecture lets you defer decisions for as long as possible. But here’s a PROTIP: if you’re using Rails, you’ve already let someone else make a lot of decisions for you. That’s kind of the point since Rails is largely a curated set of Rack extensions that help you build web applications. They’ve decided your app layout. They’ve decided you’re going to be using MVC. They’ve decided you’re going to be piping things through a router of some sort and dispatching those requests to objects. All of these decisions and many, many more are already made. So, why waste the effort to whine and complain and hand wave that it’s bad, when you’re doing it to yourself? Pick a different framework or build your own, problem solved.

Seriously, wtf?

Those are just the major points I had issue with. There were several other minor things that grated me:

At 17:00, he makes the remark that only classes derived from ActiveRecord::Base go in app/models, not the business objects he’s describing. I know he was making a sarcastic remark since that’s a general practice he disagrees with, but it (a) fell flat because a bunch of people yelled ‘models’ when he asked the baiting question and (b) is a fairly well known fact these days you can put anything in there that’s a business object.

Around 25:00, he takes issues with “web stuff” like session id’s and so on getting into your business logic. The problem with that is that sometimes you need that stuff. There are many times where I need to know how to handle some logic because of a header or some other payload information from the web.

Around 33:00 he makes a snide argument that “You gotta know a ton of languages to write a web app.” Seriously? You really only have to know one programming language. If you want your pages to look decent, you need to know one markup language (and optionally know a second programming language if you want some fanciness). What about desktop apps? You need to know a form designer or a mark up like XAML/WPF or how to manage frames and such in code (which isn’t any easier than just learning a stupid mark up language). The criticism is weird because the best part of the web is that we have standard, interpretable languages/mark up usable by clients that don’t require client knowledge of any specific programming language. I can write a web app in Java or Rails and the client, which could be a mobile phone, desktop computer, mainframe in the tundra of Russia, or whatever, doesn’t give a crap which one it is. That’s awesome not annoying.

Around 40:00, someone mentions they have “too many tests.” He goes on to dismiss that attitude (2 or 3 times actually) as a symptom of slow tests, and continues to point out that you should never get rid of tests, just write faster ones. I hope he’s kidding. I can tell stories of many apps I’ve inherited apps that were way overtested. I’m talking 5,000 Cucumber scenarios for an internal, non-mission critical application over-tested. I mean 22,000 unit tests for 30 models over-tested. I mean if I tweak the content of a constant array, the right tests fail, but I also have to clean 5 other tests where they simply tested the content of the array. That’s over-testing. I could rant about this for a while, so I’ll stop. :)

So, seriously, what happened? I think I’m just so disappointed because I’ve seen better stuff from him, but how have people been pointing to this talk as a really important talk that everyone should watch? I get he wants us to DECOUPLE ALL THE THINGS, but do we look past all this crap to get to a point he could have made much more directly and honestly (and in only about 10 minutes)? Or am I missing some grand overarching sarcasm that has placed me in the unenviable position of being part of the conference session equivalent of Punk’d?