Archive for May, 2007

Ayende made me laugh again:

I should qualify that with saying that I am also a lazy person by nature, therefor I would tend to learn just enough to get myself out of problem.

I believe all good developers have a lazy gene in them. Not the slacker gene, mind you. There is a difference. The slacker gene causes developers to do all sorts of bad things, like cut-and-paste code, or skip unit testing because “it’s just faster to write the code.”

But the lazy gene is the catalyst for good programming; it brings about solutions to repeating problems. The lazy gene is the one that prodded someone to write the quicksort, or develop an O/RM because writing data access code is repetitive and boring. The lazy gene prods developers to write tools to become more efficient because repetitive coding injures the brain like repetitive motion causes injuries. The lazy gene causes a developer to say, “Hey, this code exists in three places, I’m going to extract it into its own class and refactor.”

Developers who possess the lazy gene feel pain when they experience code that is repetitive, cumbersome, or hard to use. That pain prods them to refactor their code into something more useful and maintainable; it prods them to build a better solution, or tool, or whatever, so that not only do they not feel the pain anymore, but so that they can ease the suffering of other developers as well. Fellow developers then feel the burden lifted from their shoulders thanks to the work-product of a lazy gene developer. Their lives become easier because they can sit in front of their computer plugging away at Visual Studio with ReSharper installed…

Final (almost unrelated) thought from the RSI wiki:

A repetitive strain injury (RSI), also called repetitive stress injury or cumulative trauma, is any of a loose group of conditions from overuse of the computer, guitar, knife or similar motion or tool.

I’m a developer and a guitar player. I also do the vast majority of cooking in my house… I feel so doomed…

In response to my Tools Are Not Evil post, Ayende writes this morning:

Tools can make you more effective, but I think that you should always learn without them.

I just want to take a moment to clarify something: I agree with Ayende on this one point. When it comes to “learning” as a computer programmer, I think it is always a good idea to take the tools out of the equation and learn what’s actually happening.

But “learning” and “working/using” are two completely different things. It’s fine (and recommended) in acedemia to strip users of tools to they “learn” the inner workings of things. I’ve written in MIPS assembly language as an undergraduate to understand how the CPU parses instructions; written a Java compiler compiler to learn how languages are created and the differences between them; written a virtual operating system so we could see how memory allocation worked and so on.

Those are all neat acedemic exercises and help make us better programmers because they give us deeper understanding, but when do we do that stuff in a real workplace? When was the last time I wrote a compiler? Not since I was an undergraduate.

So yes; I agree. Learn first without tools. But once you know how or why something works, and you’rce forced to use something in a real work environment, it’s time to put the acedemic hat on the rack and put the work hat on your head, and get down to business. And part of that busines is being efficient, which means taking advantage of tools.

As far as something being flawed if a tool is required; I disagree with Ayende’s sentiment there. Here’s my basic belief about tools: they are the evolution of what we do as programmers, and if our discipline evolves the tools will evolve as well.

Ever watch Star Trek? Recall how the captain just has to “ask” the computer to do complicated stuff, and behind the scenes I’m sure its doing some programming… I hope 100 years from now programming has advanced to the point where we’re not writing Boo in notepad. In order for that to happen, the tools will have to evolve.

This post from Ayende made my laugh this morning. Specifically this:

if you need a tool in order to effectively use a piece of software, then you are already in a losing position.

I’d tend to say the opposite: if you’re not taking advantage of tools, you’re leaking efficiency.

In comments, Ayende wrote:

I write applications in notepad + command line, I am weird, I know…

Ayende talks a lot about “pain”. I can’t imagine anything more painful than writing code in notepad. I did that as an undergraduate; C on Unix with XEmacs and a command line compiler (Ok, so it wasn’t exactly Notepad; XEmacs is a step up, but it still wasn’t what I’d consider to be a true IDE, at least not without a lot of tweaking and editing). Fortunately programming tools evolve, as do most programmers.

I can’t imagine the pain that I’d feel if I had to write .NET without the IDE and ReSharper, for instance. Actually, I can. A few weeks ago I downloaded the XNA framework because I wanted to do a bit of game programming. My home machine did not have a license for ReSharper and instantly I felt the pain of having to work without it. I missed its ability to intelligently inform me about missing references, or gray-out unnecessary code. That didn’t make it impossible to write code, it just made it uncomfortable. I lost efficiency as a result.

I don’t look at tools as a handicap; I see tools as a way to make us more efficient programmers. And in a world driven by rapidly changing business desires I think it behooves us to have the best tools possible so we can be as efficient as possible. Efficiency is our lifeblood. Most companies don’t have the capital to support the Blizzard tenet of, “We’ll release it when it’s done.”

If you look at just about everything else in life that involves creation you will see that the tools have evolved. For instance, we don’t build skyscrapers with the same tools we did 100 years ago. We don’t build cars with the same tools we did 50 years ago. Musicians don’t even create music with the same tools they did 20 years ago. The tools evolve based on a singular purpose: to make the person more efficient at doing the job.

I find it particularly ironic that Ayende advocates building tools to take away pain points, but criticizes P&P for doing exactly the same thing. Then he says he writes in notepad + command line, which I can’t imagine anything being more painful. It seems like a real double standard.

At any rate, Ayende’s claim (that you need tools to use CAB) is wrong and fortunately Glenn Block corrected him in the comments. You don’t need SCSF to use CAB. In fact, for the first year of development, our shop didn’t use the SCSF. I built the first CAB application at work with just the API and some documentation. The bulk of the value for the SCSF comes with initial application creation. We later moved to the SCSF for one reason: so we could right click and generate the three class files for MVP. It only saves a few minutes of typing, but every edge we can get in development is worth it, in our eyes.

Efficiency is our lifeblood, after all.

Nicholas and John commented about something that I think is central to the recent CAB/P&P discussion: documentation. There’s a severe lack of clear documentation when it comes to CAB and I think it is affecting a couple of things. First, I think the lack of documentation creates a barrier to entry; people can’t immediately grasp the power or ease of use of the CAB because there’s nothing that shows it being easy. Second, the lack of documentation causes people to turn to other methods for learning: blogs, reference implementations, inspections. All of which lead the user to think it must be difficult to use. That is part of what creates comments like these courtesy of Ayende:

Nevertheless, “We actually don’t find CAB that hard anymore” – that is after over a year of working with it, right? I would say that it would have to be hard to use after that period of time. Incidently, this is not the only reference for about a year to get the CAB.

And this comment:

About the complexity of the CAB approach, just a few quotes (hopefull not out of context):

* From Sam Gentile: “…I was going to show how to tame this CAB beast…”
* From David Hayden: “I have never had the pleasure of working with the Composite Application Block ( CAB ) or Smart Client Software Factory ( SCSF )”
* From Bil Simser: “I’ve spent the better part of a year learning CAB, EntLib, ObjectBuilder, WorkItems, and all that jargon…”

Complexity is not a good thing, especially when it is exposed to the user.

Here’s the thing: CAB is not hard to use. What it is: flexible, rich, heavyweight. And I do not use that last term negatively.

Sidebar: This post is not about lightweight vs. heavyweight. I know Ayende likes the lightweight approach to his tools. I think that’s a completely valid choice. I also think that a heavyweight framework that attempts to solve a lot of related problems at the same time is just as valid of an approach. In my opinion, which direction you choose is completely personal and should be researched well and fit your business situation. Both approaches work. I think the important thing in both approaches is that regardless of whether you use a lightweight approach or a heavier framework the underlying approach is rooted in solid design; IoC, MVC/MVP, sticking to good design patterns, loose coupling, testability and maintainability. These things must rule, not the specific implementation. End of sidebar.

Let’s address the Year Long Grok.

There are a couple of factors that made grokking CAB difficult. The first thing was that when CAB was released the documentation was thin. I mean razor thin. That’s fine for something simple (meaning: something that solves one problem, not many). You can just sift through a reference implementation or a piece of sample code and get the gist of it. NUnit is like that; just a quick example of a unit test and you know what the thing is capable of. CAB is much more rich and heavyweight than that; it’s a framework designed for solving more than one problem, and when you have something that can solve multiple related problems then a simple reference implementation or a quick look at some code is not going to cut it. You will not gain full, deeper insight with that sort of cursory documentation effort.

I got in on CAB during the final two CTP’s and there wasn’t much there except a reference implementation that showed how you could possibly use it. Notice the use of the word ‘could’. Part of what makes CAB difficult to grok is that it is flexible. There are a lot of ways to solve problems in CAB, and the framework does a pretty nice job of not forcing one particular way of doing things on you. This fact can be witnessed by the sheer number of forums posts during the first two years of CAB’s life where users asked questions like “how do you do X?” and there would be four answers, all different. I find a lot of power in that, but it also creates a lot of responsibility for the developer; you have to know what you’re doing as a designer; you have to build your solution property to fit your needs.

There’s also one other variable to this equation: knowledge. There are a lot of developers working with CAB would aren’t as learned in the concepts of design as folks like Jeremy and Ayende. The lack of design knowledge creates a problem grokking CAB, because they don’t understand the concepts that the CAB is based on. So for them, grokking CAB isn’t just grokking CAB, it’s grokking design patterns, IoC, loose coupling, testability and other key aspects at the same time. It’s like your first time reading Shakespeare as a teenager and having to reach for the dictionary every 5th word. It can be hard to get the meaning of Shakespeare if you’re having to learn the vocabulary at the same time.

CAB is an entry point into the Agile world and into the realm of good design principles, kind of like Shakespeare is an entry point into great literature. Whether folks realize this or not, this is an important fact. So a lot of people are discovering CAB and Agile and design principles all at the same time. A lot of people are being exposed to CAB, and at the same time they’re being exposed to MVC/MVP, IoC, testability, loose coupling and a lot of other good design principles. It can be a lot to grok. And since they are doing it all while learning CAB, it bloats the CAB learning curve. In short, they’re having to reach for the dictionary every 5th word.

So how can something as robust and rich as CAB be exposed as simple and easy to use?

How do you make Shakespeare easy to comprehend?

Cliff Notes. I think good documentation could go a long way toward getting folks to grok CAB in short order. Cliff Notes on CAB. Users have to understand that CAB isn’t hard to use. They have to be able to see CAB’s features in their purest, simplest form so they can see what problems its solving and how it is solving them. They have to be able to see these things isolated and concisely described, with references to the important or relevant background principles if necessary, so they can get a full understanding of what’s going on.

Because if you can’t show a user the advantage of using the CAB – if you can’t show them what problems it is solving and how it is solving them – then the whole point of building it is diminished somewhat.

At any rate, I just wanted to address the whole Year Long CAB Grok. I think there’s a lot more to it than just “CAB is complex”. CAB is built on a lot of principles and patterns, plus it solves more than one problem. Roll that all together and you’ve got a lot to absorb as a developer trying to learn a new tool.

Jeremy Miller joined the fray. He comes down in support of Oren’s post. Then there’s this post by Adi. He more or less comes down in support of my post. But the most startling thing I read was this:

I have been reading another post war (I bet Oren really enjoys them) between Oren Eini and Chris Holmes.

Wait a second – there’s a war here? When did that happen? Why does every “conversation” on the blogosphere have to be a “war” when even the slightest of opinions differ? Can’t people with different opinions have a civilized conversation without it being a “war”? I know they can, because Oren and Roy did it a week ago.

I’m guessing that this appears as a “war” because of my own poor writing skill. I conveyed my thoughts poorly, making it sound like I disagree with Oren, and as such now people think I’m on some “side” opposite him. But the reality is much further from that.

I’ve always been a guy who believes in “build it yourself”. I look for that same attitude in people we hire. The reason for that is because 95% of the time when you look for a solution off the shelf, it won’t do exactly what you need it to do and you’ll have to spend a lot of time customizing it, adapting it or altering it to fit your needs. Wasted time, especially when you could have just written it yourself and it would fit your needs 100% with no additional baggage.

So does that sort of belief put me very far from guys like Oren and Jeremy? I don’t think so. I think, actually, we’re very much alike.

There is one thing I don’t believe in, however, and that is absolutes. I don’t believe that one language is king, or that one vendor is king, or that one way of doing things rules every time. I don’t believe that building something yourself every time is always going to be the answer. I leave open the possibility that there might be another solution. I believe in the Toolbox; a place where you go to find the best tool for the job. And every job is different.

A Quick Response To Jeremy

And yes Chris, I’d much rather use my own fully-featured StructureMap tool than deal with the very limited ObjectBuilder DI tool embedded inside the CAB. Guilty as charged.

You know what? I’d be shocked if Jeremy felt any other way. I’d also be disappointed. He built StructureMap; if it wasn’t better than the other tools (in his eyes) then he should be using whatever he thinks is the best.

I’ll also say this about ObjectBuilder : I agree with Jeremy; I wouldn’t use it on its own. It’s hideous. It is overly complicated, undocumented and cumbersome. It is the worst part of EntLib and CAB. Fortunately, when using EntLib and CAB I don’t have to manipulate ObjectBuilder. If I did, I’d have abandon both tools a long time ago.

So we come to this question: If I don’t like ObjectBuilder, then why am I using CAB or EntLib?

The Decision Making Process

I said I think every project is unique. But not just the project, also the environment surrounding it. The forces surrounding a project determine how I approach solutions. Oren and Jeremy stick to their guns a bit more than I do when it comes to the “grow your own” tenet. I want to make it clear: I don’t think that’s a bad thing; and I don’t disagree with them. They do what works for them and I think that is the responsibility every developer has to deal with.

Why did I choose CAB? Because at the time, I knew there were things we would need in our code base to help us be productive. I had two options: roll my own, or choose something that provided the functionality for me. I looked at IoC containers and I looked at CAB. The latter looked to me like it had a lot more functionality out-of-the-box than an IoC container. EventBroker, CommandHandlers, Workspaces, WorkItems (the IoC container), support for MVP… It looked like a lot of the features we would build ourselves were already there. And it also looked like we wouldn’t have to adapt or alter large chunks of the source code to get what we wanted.

Now, some people might say “that’s Big Design Up Front”. I’d argue otherwise. Our ultimate goal was testability. We wanted to adopt an MVP architecture so that we could have a very testable UI layer. We wanted automated tested; we wanted automated builds; we wanted the confidence that comes from having a vast suite of unit tests; we wanted the confidence to refactor our code without fear of breaking a tightly coupled system. So our goal was not to have “nifty tools”, but to have a framework to build upon that would give us our ultimate goal: a testable UI layer that we all would have confidence in.

With an IoC container I would have still had to develop a lot of functionality myself. I wasn’t afraid of doing that (and I am NOT against that), but I also didn’t know how much time it would take. My assumption was that it would take a considerable amount of time (and not as BDUF; but as time spent building the pieces when necessary. The bottom line is, it still takes time, no matter how you allocate it, and I wasn’t certain how much). That assumption was probably unfortunately influenced by looking at the CAB as a frame of reference and saying, “Holy cow, there’s a lot there…”

So we went with CAB. The idea was that we thought it would help us get out of the gate faster. I thought it would take less time to grok the CAB and make use of it than roll my own code. Maybe that was an error in judgment. It’s certainly possible, I am human and very flawed. But I did manage to grok the CAB pretty fast compared to other adopters, so it seemed like a good decision to me at the time.

Would I Make The Same Decision Again?

In the end, we got what we wanted. We got a very testable UI layer, and we got it with minimal pain and effort. Yes, the CAB can appear complicated at first, but once I grokked it it seemed very easy to use. Yes, the CAB does things in a strange way at times; there are points where you look at the code (Controlled WorkItems being a primary example) and go, “Why the hell did they add that layer of indirection? It just makes the whole thing more complicated”.

But fortunately, the CAB isn’t a tool fixed in stone. It’s very easy to tweak it to do things the way you want it to do them, at least in many of the more frequent scenarios. And that’s what we’ve done to remove some of the complexity. We just use the CAB but we make it more simple. Of course the obvious comeback is, “Why not just build it yourself?” Which is the thrust of Oren’s argument. And he’s right, I think, in many respects to ask that question.

I chose CAB because I thought it was the best solution at the time, given everything I knew about software design and weighing all of the other factors involved. I might make a different decision today, given the amount of knowledge I’ve accumulated and the tools that have emerged. I might do just what Jeremy and Oren propose, and grab an IoC tool like Castle and grow my own solutions as necessary. That sort of thing appeals greatly to my “do it yourself” attitude.

But I don’t regret choosing CAB. We’re productive with it. It gives us good value for very little effort. It doesn’t cause us pain. And it doesn’t appear complicated (at least to me).

The Bottom Line

To me, the most important thing is delivering tested, maintainable code that meets the customers needs in a timespan they can stomach. And whatever tools or tenets a person uses to reach those ends, I can’t argue with if they’re achieving their objectives.