I wrote some of this on a 5:40 AM train. After this I’m not going to write any more commentary type posts on far too little sleep. Besides little mismatched rants, I’m flushing out bits and pieces of blog drafts that just never escaped into the wild. Think of this as a personal ablution to rid myself of negative thoughts from the past couple weeks – or a sacrificial anode to keep the metaphorical rust of ranting out of my posts for the next couple weeks.
Just to let you know how far back this detritus goes back, I found this quote at the bottom of an unpublished post:
By the way, the last thing I remember saying at work today was “Ohio State just has too much talent for Florida.” I hope my discussion about maintainable code is more on the mark than my game predictions tonight.
Just in case you’re wondering, I meant the college football championship in January. The basketball championship in March was pretty easy to call.
Embedded DSL’s HOT, Programming with Xml, and Fun with Attributes NOT HOT
Just adding to Roy’s Hot/Not Hot blog post. The above isn’t completely true, but I wish it was. I thought about this when I read through Ayende’s not entirely complementary commentary on Acropolis. I mostly agree with Oren on this one. I’m perfectly fine with the Acropolis team adding all the designer support, as long as the levers are all exposed so I can wire up the MVP and service pieces with an embedded DSL of some sort instead of using the designer.
There’s a quote from Martin Fowler that I like to paraphrase is “the only way to know how useful something can be is to overuse it then pull back.” We’ve hit that point a long time ago with “Programming with Xml” and I think we’re well on our way with using attributes to describe behavior. This whole idea that anything is automatically easier because it’s configurable with Xml or a visual designer needs to be reexamined. I’m much more interested in moving towards little lexical languages embedded in C# (with Fluent Interfaces now, but it’ll be easier in C# 3.0) or Ruby to do wiring declaratively. Instead of the Acropolis team (or the EF team for that matter) saying that it’s going to be easy to use because of designers/wizards/attributes/xml wiring, I’d rather they be able to walk up and say it’s going to be easy to use because the API for controlling or describing the desired behavior is easy to consume and read.
Why would I want to eschew all that visual wizardry for something as crude as code? Here’s a start:
- People can read English, but angle brackets are a different story
- I can debug code
- When I’m using an embedded DSL I still have the full power of the containing programming language.
- You can express more signal with less noise in a textual language than you can be poking little bits of important information behind designer screens
- The behavior of the application is much easier to understand because it’s expressed in a denser format. I feel pretty strongly about this one. I think the results of RAD programming obfuscate the intent of the code. Maybe the graphical DSL’s that MS is pushing won’t suffer from this problem, but I’d bet that textual DSL’s turn out to be the better path in the end.
Something to note, if I take steps to make my code easier to deploy, the advantage of describing behavior through Xml configuration largely goes away. I have some metadata driven things in my current system, but I’m doing the metadata with a simple declarative, fluent interface rather than putting it in an external Xml dialect of some kind. I fought my client’s armchair architect on that a little bit, but whether or not we deploy new assemblies or new Xml files is the exact same XCopy operation, so why not do it the easier way and put it directly into the code. Now there’s no way my code and xml can get out of sync because there is not xml.
I’ve said before that development trends start in Java and dribble into .Net. I hear a lot of complaints about the amount of Xml programming in the Java server stack these days, and I’ve experienced it in the last two months as I work with Spring, iBatis, Apache Axis, and other things. Not that .Net doesn’t have it’s own XmHell problems too, but let’s sit this trend out please. The reaction to the perceived Xml programming pain in the Java server stack seems to be a fair amount of what’s driving the “convention over configuration” philosophy of Ruby on Rails.
What makes for Maintainability
Frans Bouma has some comments on Sam’s It’s so true post on maintainability, and more scattered on Ayende’s Maintainable for who post. He’s got a solid point on documentation to describe the “why” of a system’s design. It certainly helps to understand why a system arrived in the state it’s in, and I’m very much in favor of the entire development team understanding the why. Granted, I’ve got an almost knee jerk reaction to disagree with Frans on almost anything related to software development, but I’d still prefer a much stronger emphasis on the “what” and “how” a system is put together than I would the design documentation.
You’ll notice in all of the writing I’ve done on maintainable software that I didn’t say anything about documentation in regards to maintainability. It’s not just because I hate writing documentation (I do of course), I just think it’s much more important to focus on writing good code that is easy to understand. Some documentation is obviously valuable, but given the choice between:
- Copious documentation about poorly written code
- Minimal documentation on solidly written code
I’d pick number #2 in a heartbeat. You can’t maintain badly written code under any circumstances. I don’t really care so much “why” it was written that way, only what it is. And by solidly written code I mean code that I can understand by looking at that readily accepts change. Besides, I’ve never seen a long technical document that was entirely useful. Time and manpower is finite. I’d rather sink more energy and resources into better, cleaner, well-structured code than comprehensive documentation because I think the payoff is higher. To me, one of the biggest advantages of moving from a waterfall shop that produced a lot of intermediate documents to XP shops was that I now get to spend much more time on a project focusing on the design, architecture, and code than I did when I was on the hook for much more documentation. I write fewer documents, but I get to create better code with far better configuration management practices. I call that a net win.
For that matter, I’d rather shift documentation efforts to executable specifications and automated build scripts. I honestly believe that a full automated build script does a more effective job of documenting a systems environmental dependencies than a Word document ever could. Executable specifications (you can intersperse prose in the tests to your heart’s content) can be far more detailed than a traditional requirements spec. Solid build scripts do a helluva lot to make a system easier to deploy and get up and running on a new developer’s machine. More than mere documentation does anyway.
My contention is that if you do all of these things, the necessary documentation becomes very small.
TDD and Maintainability
As a quick aside, Frans also more or less makes the claim on Sam’s blog that TDD doesn’t do anything for maintainability, or just wonders what in the world it does do for maintainability. I’ll take the bait. I’ve found TDD to be very advantageous for maintainability, and here’s why (from experience in case you’re wondering):
- Orthogonality. Codebase’s developed with Test Driven Development will almost always exhibit better qualities in regards to cohesion and coupling, the very same qualities that make code easier and safer to change. I know Frans is going to come back and argue that he gets it done with lots and lots of documentation and very careful upfront design. I’m going to respond to that by saying the instant feedback loop from doing detailed design with TDD pushes me in the direction of orthogonality more efficiently and effectively than any form of upfront design. Why is this true? Because you can’t use TDD on code that isn’t loosely coupled and not easily on code that isn’t highly cohesive.
- The unit tests are a form of documentation. Reading the unit tests for a class should be a great way to learn how to use any given class. I can think of several cases where someone else’s unit tests have made it easier to use a class or API.
- High levels of unit test coverage gives you so much more ability to change existing code without introducing regression errors. No matter how much upfront analysis and design you try to do, the users will always come with something completely new that you couldn’t reasonable anticipate in your initial construction. It’s awfully nice to have that immediate safety net of focused unit tests as you make changes to existing code. Documents are passive. Unit tests will shout out when they’re broken — assuming anybody runs them of course. Good unit tests will even tell you exactly where the regression breaks happen.
No, TDD most certainly isn’t everything, but it’s something.
Handoff’s between teams or disciplines are such a huge source of waste in development efforts. I wonder if one day our management types will ever catch on to this fact and start facilitating better collaboration and worrying more about retention. Just like shipping water over a long aqueduct, tribal system knowledge evaporates as it’s passed from person to person, especially if the transmission is only through paper. My client is somewhat concerned about transitioning the system we’re building to their developers (as well they should be). I’ve got an easy answer, put one of their developers on the project so that the transition isn’t abrupt. No amount of paper will ever give convey the understanding of a system that you get from building it in the first place.
Something that I see over and over again is that the very tools and abstractions that are supposed to make development easier are exactly the things that make a given task harder than it has to be. My target for villainous slurs today is data binding in WinForms. We needed to create a feature today to automatically update the backend when users clicked checkbox’s in a databound grid. The 3rd party grid (not Telerik because I know they read this sometimes) didn’t specifically enable or envision this scenario, and guess what, it’s hard to do with their grid. Data binding makes filling the grid really easy, but the code to do synchronous events was a bitch. Data binding is good because it makes common development tasks simple. Data binding is terrible because it makes anything that the designers of data binding didn’t intend much harder than it probably would be from scratch — assuming that WinForms had better layout managers for dynamic layouts. I hate technologies and tools that punish you for coloring outside the lines.
Why is this ALT.NET stuff elitist?
We really need to change the perception that stuff like TDD/DDD/IoC/ORM/CI/Unit Testing is just elitist stuff. All we’re doing is striving for better software development results, and these ideas represent some of the ways we can write better software (until better and better things come down the turnpike of course). I can’t use this stuff to it’s fullest potential if the developers around me aren’t familiar with the techniques or management is hostile to anything originating from outside Microsoft. These things become much more useful when they become mainstream.
I liked Scott Hanselman’s treatment of this (except the inevitable appeal for Microsoft to do something about this bugs me):
Why does this have to be ALT.NET? Why is this alternative? Seems that this should be mainstream and baked in by the tools and “dogma” that comes down from on high. Microsoft needs to make ALT.NET attitudes Mainstream.NET attitudes, through leadership, openness, and a lot more prescriptive guidance.
I don’t buy off on the idea that we almost have to use the drag n’ drop / RAD programming style because that’s what average developers know. How in the world are they able to know *that* stuff in the first place? Beyond little trivial tasks, RAD programming in .Net requires a lot of knowledge too. The WebForms page lifecycle is one of the most complex, convoluted things in mainstream development today. If you can learn that little monster, using IoC or NHibernate is going to be a snap. The reason that “average” developers know the RAD stuff is because that’s what they’re exposed to. If .Net developers started with codecentric techniques first, before they ever see any RAD, I betcha our community would be vastly better and more effective.
So, what does work?
There’s constantly arguments and debates flowing on the best way to write software. Many of us actually manage to invest quite a bit of opinion, knowledge, and experience into specific approaches like Extreme Programming. Almost any time there’s a debate some weak minded clown tries some cheap theatric attempt to permanently seize the high ground by stating that “I’m the pragmatic one because I say you should just use what’s best for a particular situation” or this old chestnut “pick the best pieces of waterfall, RUP, and Agile.” That’s nice. Nothing but empty calories devoid of any intellectual value, but nice. It does leave us right back at the beginning again — so what does work? I know it’s a bit irritating to deal with people that have strong opinions, but I’d have to ask, how can you have years of software development experience and not developed meaningful opinions on the best way to build software?
If there’s anything useful about the low level buzz about the new ALT.NET moniker, I think it’s simply to start a conversation in the .Net world about better ways to build software. I know people are already getting upset that it’s elitist and putting down the average .Net developer. That might be true, but I’d have to say to just about anybody, do you really think the way you’re doing things is the best possible way? Or is it just what you know right now? If you don’t like the ALT.NET stack and approach, tell me why not and let’s get the discussion going. Just calling me elitist isn’t a real position on your part.
I’m too busy solving business problems!
I build real systems and by and large I feel like I live in the real world. This idea that things like TDD/DDD/ORM/IoC/Continuous Integration/Test Automation or whatever else is just academic hot air or merely shiny toys for the alpha geeks really worries me. I frequently see somebody say something like “we’re too busy solving business problems to spend time on this ivory tower crap.” It’s a self-defeating attitude. It’s the I don’t have time to sharpen the saw, I’m too busy chopping wood! syndrome.
Do you know what’s a really big problem that impacts the business? Technical debt. Code and software ecosystems that are hard to maintain and change. If I can create an enterprise system that is easy to change, I’ve opened up more opportunities for the business to ask for more functionality. If I write code that’s hard or risky to change, I’ve closed off opportunities to the business. All of the acronyms listed above are techniques that people are developing and using in an attempt to create code more efficiently with better qualities for maintainability. Maintainability is crucial for your ability to keep delivering value to the business over anything but very short timelines. Think on that Mr. “I’m too busy delivering business value.”
Being skilled in our profession is pragmatic. Purposely remaining unskilled in your chosen field is not. Before you start whining about the continuous learning entailed in remaining a software developer, remember that you make a heckuva lot more than the average person. Besides, do you really want a job where you never get to do anything different or ever learn anything new?
I’m not saying we all have to be a Jeffrey Richter and memorize the Win32 API (shudder), but we’re better off when we have a basic understanding of what our fancy wizard tools are doing under the covers. The idea that you just learn enough to kind of make the technology go a little bit is not practical, it’s playing with fire. Fire good, so me put more gasoline on fire. Wait, where me eyebrows go?
I know what I’m talking about here because I’m in this boat myself at the moment. We’re using my client’s standard Java OSS stack for creating web services in Java (and if you want a definitive reason to use .Net instead of Java, go write web services in both environments). It seemed like the right choice, and probably will be in the end. The stack comes with a huge pile of prebuilt Maven scripts to perform basic tasks, builds, and development deployment. The problem for me comes from the fact that we don’t understand what the Maven scripts are doing. All we know is that pulling Lever A seems to produce Result B. But if anything goes wrong, and it frequently does, woe is me because I have no idea how to diagnose the problem. In the .Net client ecosystem our NAnt scripts are small and very well understood. I intimately know what’s happening under the covers and I can fix any problems. So, just to keep score, the scripts that I wrote by hand aren’t giving us the slightest bit of problems. The scripts written by a wizard created by someone else, lots of headaches. Headaches to the point of having the intern write little Ant scripts from scratch to partially replace the full figured Maven scripts.
On Opinionated Frameworks
At my new .Net user group the other night a couple of us were talking afterwards about the desirability of “opinionated software” frameworks. At the same time, there’s (inevitably) a discussion going on at Ayende’s blog on using frameworks. Simultaneously, David Hayden was talking about being wanting to use a tool from P&P, but leave the EntLib on the sidelines. The usual suspects are showing up: Ruby on Rails & MonoRail, CSLA, and CAB. The common thread is that these tools force you into developing a certain way with a certain structure. I think the real question is whether or not one of these opinionated frameworks is a good choice, plus some frustration at the choices these tools thrust upon you. I think it’s very simple in a way, if you agree with the framework’s “opinion,” and it does exactly what your application needs, go for it. Otherwise, if you’re fighting with these tools to make them fit your opinion of how the world should work, you’re simply better off to leave them alone and go your own way.
I’ve been pretty clear several times that I really don’t care for the CSLA approach and design. I haven’t used it since the VB6 days, and never by choice even then. Anytime someone talks me into giving it another serious look I end up recoiling in disgust pretty quickly. So back to the idea of opinionated software, is CSLA a good thing or a bad thing? *I* think there are better choices for structuring an application, but there’s absolutely no doubt that a CSLA based application beats a ball of mud hands down. CSLA might not do much for me, but an inexperienced team with little or no design background may be very thankful for the guidance in CSLA’s “opinions.”
The Java Community versus the .Net Community
Here’s a question that I’ve been rolling around this morning. Is it possible for any practice or technique that doesn’t originate from Microsoft or get pushed by Microsoft gain any traction in the .Net community? Why is it that the Java community seems to be perfectly capable of making their own minds up about best practices and then telling Sun, but the .Net community ignores anything from outside while taking anything MS puts out hook, line, and sinker?
The .Net community uses RAD techniques just because that’s what Microsoft puts out. Object/Relational Mapping is still very rare in .Net, and I bet it’s mostly because Microsoft still doesn’t have an ORM in production release. Inversion of Control tool usage is rare in .Net (even though it’s been available at least since StructureMap was released in June 2004), but I bet it got a lot more traction after the P&P team released ObjectBuilder in the CAB.
I asked Ted Neward about this at DevTeach and his almost immediate response was that Sun wasn’t as good a software vendor as Microsoft. Make of that what you will I suppose.
Just do the best you can
From a running commentary on Ayende’s post Maintainable, but for whom? One of the commenter’s is voicing some frustration about the whole TDD/IoC/ORM stack as unrealistic practices or techniques in his situation. It’s a common story. Forget about the specific practices he enumerated, there is always something wrong with your situation that retards your progress or limits the practices you use or the way you want to work. I’m not using anything close to pure XP because I just can’t get away with it in my client. I would dearly love for my client to use executable specifications for requirements, but we simply don’t have the resources from them to interact with us to write the executable specification documents. They want to write RUP-style use cases and just throw them over the wall because the business experts just don’t have time to interact with us too much. You don’t just pout and take your ball home. You just play the cards you’re dealt the best you can and hope for the best. Specifically for XP, if you have to drop something out of the 12 practices, you simply have to put something else in to take its place.
Get a thicker skin
I’ve been disgusted with the blogosphere lately. Specifically, the level of thin skinned sensitivity is making any level of discourse nearly worthless. We can disagree in a civil way, and that’s exactly what I see happening the mass majority of time. I’m completely sick of the whole “You’re a zealot!/Blog war!” crap anytime somebody else merely has a strongly worded opinion or makes any expression of disagreement — even in the complete absence of anything impolite. It’s a cheap way to try to end an argument. Yeah, there’s an unhealthy amount of vitriol on the web, but let’s stop describing a simple debate as a “blog war.” Conversations that revolve around a difference of opinion are vastly more valuable than a lightning round of “I agree with you. No, I agree with you more!”
And one more time, if someone criticizes your tool or practice of choice, it’s not necessarily a personal attack. Lastly, if you make an opinionated post that’s obviously going to cause a reaction, you better be ready to get some comments and replies that are going to be argumentative with you and your opinion.
A couple years ago there was a little bit of an uproar about the steady flow of coding examples that in passing used a Sql Server connection string with a blank “SA” password. Obviously, putting a database out into production with the admin password blank isn’t something to encourage, even accidentally, so using a blank SA password in code examples became a taboo. I’d like to create a new taboo, there will be absolutely no, none, nada, zip data access code in ASP.Net or WinForms code behinds in any published coding examples. Just put a method or empty class in that goes “//fetch the data here.” I don’t want to even give a hint to new developers that doing data access inside UI code is an acceptable idea. New developers should be taught to feel dirty and shameful about a complete lack of layering.