Monday, July 21, 2008

Tag Soup sucks: Hey Jeff, here's a better way

Jeff Atwood of coding horror posted about "tag soup" in web development. I absolutely agree with him on this one: every web development framework currently in existence renders crap HTML code. Remember my HTML wall of shame? Yes, that's a good example of crap HTML being rendered by frameworks. Jeff (Atwood) asks if there's a better solution. Luckily, Jeff (me) has one: it's called writing good HTMLand separation of concerns in rendering. Wow, that's a long phrase. Let's try again: Don't use frameworks because you don't know HTML; the people who wrote the framework don't know HTML either. No, still not good. Let's stick with the old favorite:

It's called HTML and it's not hard

That's right, HTML is not a complex thing and writing clean HTML isn't particularly difficult. In fact, you can leverage a framework and still write good HTML and I'm going to show you how. It's really as simple as using separation of concerns. Let's analyze the various parts of a web page.

HTML

What is the HTML for? It's really a place to store content. Your text, your menu bars, your stupid scrolling marquees, your <blink> tags, etc. All of this goes here. The way I think about it is that you're using HTML tags to create containers for content. A <p> tag is a container for some text. A <table> contains some related data in rows and columns. A <span> tag is going to hold some special line of content. A <div> is going to contain some special stuff inside of it. Notice that I haven't said a thing about formatting, style, or actual content yet. The reason would be that it DOESN'T BELONG IN YOUR STUPID HTML!!!!! One more thing I'd like to bring up here is the hell of nested tables. This occurs when someone wants to do some sort of complex formatting and doesn't know how to use the div tag with CSS. Nested tables are an anti-pattern called "Nested fucking tables" and should be avoided. It won't make your formatting better (Firefox and IE sometimes render different table elements differently so often this actually makes things worse). This brings us to:


Formatting and Style


So wouldn't it be nice if there were some sort of "style" thing you could use to store all your styles so you can keep them in one place (DRY, right?). Maybe some sort of "sheet" where your "styles" could go, and then they would "cascade" throughout the whole site for every page that referenced them. Maybe some sort of "cascading style sheet?" Oh wait, that already exists. Let's use it! Now, you can focus on the HTML only be containers for content and let your CSS define how that content is presented and styled. Separation of concerns, right? Now you have only containers and maybe some information in the containers to identify them to your style sheets (ID and Class are the attributes you're looking for). This is good separation of concerns.


So what about behavior?


This is where the client side stuff comes in. Things get a little trickier here but not that tricky. Ok, I lied, it's not tricky at all if you actually know javascript and treat it as actual application code and not some bastardized client side tag-hiding-style-manipulating crap. Javascript is a language. It is subject to the same rules of all programming: Separation of concerns, DRY, IoC, etc. It should also have its own unit tests. Finally, like CSS, it should be extracted into its own file so that every page can consume it.

So now you have containers that can be identified, styles that can be applied to them, and scripts that can determine their behavior all in separate places. The ID's and classes of your containers help your styles and scripts know what to apply themselves to. There is a minimum of code that exists in your HTML that helps bind these things together, and in those pages that really, really are one-offs, you have inline styles and inline javascript (this should REALLY be the exception though).


But the server blah blah blah . . . .

This is where the example that Jeff shows really breaks down. I'm not going to post it up here, but go look at his post and check out the example code. You'll see something really stupidly obvious: YOU'RE DOING LOGIC IN THE DAMN MARKUP!!!! You're concatenating links, you're looping through stuff, you're doing all kinds of crap. Hell, as long as you're at it, why don't you query the database there too just so all your crap is at least in one file?

There is a simple solution to this problem: You already have containers defined by your html. Use them. Expose them to the server side code and let that code render stuff inside them. For example, in ASP .Net one of my favorite tricks is to have a table on my page and actually use the <asp:table> object so that my codebehind can expose it to my controller (You're using MVC, right?) and my controller can populate it with data. Wait, controllers shouldn't populate data, so wtf am I doing? Am I breaking my own rules? No, I don't directly populate tables from the controller; typically I use an intermediary object to do that for me (more about this in a future post, I promise). This way, the controller is able to provide the model to the view via some other object that is responsible for doing complex formatting. I can reuse my formatting objects where appropriate. I can also change the formatting without changing the model or the view itself. I can change the view even if I want to without caring how the formatting is created (as long as the contract between the view and my formatting object is fulfilled, i.e. if the view is expecting a table then the formatter had best be rendering one).


Here you go, Jeff-

A nice, happy, clean solution looks something like this:

1. The HTML provides containers for content and possibly some content as well.
2. The CSS provides style information and formatting for the containers.
3. Javascript manipulates the containers client-side to create a client-side view when neccessary
4. The server side code populates the HTML containers with content.
5. The server side uses helper objects to populate content that requires more complex rendering (tables with grouping levels I think are a good example here).

The only thing you need in order to pull this off is to know all of these different technologies. This isn't that hard, and as a web developer you really should know all of this stuff anyway. I think Microsoft started a horrible trend with Asp .Net that allowed application developers to write web apps without knowing anything about web technologies. This attitude has brought us the viewstate, page events, chatty controls, and a bunch of other crap that makes your html look like tag soup. Rails and MVC haven't helped this problem at all.

Thursday, June 26, 2008

Handling time zones in .Net is really easy

I have a project right now where we are going to implement a feature that allows an admin to specify the time zone that each user is in. When they view reports on things like system activity or similar that have a time component to them, they will see the times in their own time zone. When they request a report and specify a time, it will parse that time in whatever their own time zone is.

Time is a fairly difficult problem to handle since many different areas have different time zones with different rules. Does it have Daylight Savings time? When does that start/stop? What if the dates it starts or stops on change? What about the 25 hour day you get when you change and the 23 hour day you get when you change back? There are a lot of edge cases and a lot of time zones (for example, Arizona is on Pacific Time but it does not have Daylight Savings Time) that you have to account for. Fortunately, .Net has this nifty thing called the TimeZoneInfo class that makes this a trivial problem.

Some useful methods

There are a number of static methods on this class that are useful to the feature that I'm trying to implement. The first story that I want to implement is "As an Admin, I want to see all available time zones so that I can select the appropriate one for a user." Not a problem. I want to load them all and store them in a listbox. Here's the code:


ListBox list = new ListBox();
IList systemtimes = TimeZoneInfo.GetSystemTimeZones();
foreach(TimeZoneInfo t in systemtimes)
{
list.Items.Add(t);
list.DisplayMember = "DisplayName";
}
This will give me a list box that tells me all the time zones that are currently installed in the registries. I have a property on my TimeZoneInfo class called "Id" that gives me the id of the particular time zone, so if I want to save the time zone that a user is on, I can persist the id of that class somewhere and then use this to retrieve it:

int tzID = MyTimeZoneRepository.GetTimeZoneIDForUser(someUser);
TimeZoneInfo tz = TimeZoneInfo.FindSystemTimeZoneById(tzID);
Alternately, I can serialize and deserialize my TimeZoneInfo class in order to be able to persist it and reconstitute it in situations where I may not want or have available the system time objects. The code for that would be this:

TimeZoneInfo tz = TimeZOneInfo.FindSystemTimeZoneById(1);
//tz now has some time zone value

string serialized = tz.ToSerializedString();
//serialized is some really long string that has all the time zone info in it

TimeZoneInfo tzNew = TimeZoneInfo.FromSerializedString(serialized);

Assert.AreEqual(tz, tzNew); //should return true


This also means that I can create my own custom timezone if I want to by defining a set of rules and then instantiating a TimeZoneInfo class from my rules (I'm not going to give an example here but there's plenty of them out there).

Now, to actually use these things, I use the TimeZoneInfo.ConvertTime() method. So, if I want to fulfil my second user story, which is "As a user, I want to have all my reports reflect my local time zone so that I can see when things happened in relation to where I am" then I have a means to do so.

In order to do this, I need a UserTimeZoneRepository that gets the correct time zone for a user by their ID. First, some helpful interfaces. Let's assume that these all have implementations that do what they look like they should do:

public interface IUser{
public int ID {get;set}
}

public interface ITimeZoneRepository {
TimeZoneInfo GetTimeZoneForUser(IUser u);
}



Now, here's some code to handle the time zone problem. Let's assume that ALL times in my database are converted to UTC when they are stored there:

public class TimeZoneConverter{

private IUser u;
private ITimeZoneRepository r;

public TimeZoneConverter(ITimeZoneRepository r, IUser u){
_repository = r;
_user = u;
}

DateTime ConvertTimeToUTC(DateTime t){
return TimeZoneInfo.ConvertTimeToUTC(t, r.GetTimeZoneForUser(u));
}

DateTime ConvertTimeFromUTC(DateTime t){
return TimeZoneInfo.ConvertTimeFromUTC(t, r.GetTimeZoneForUser(u));
}
}


So why all of this? Well, first, this gives me a centralized place to handle all time zone conversion issues (Don't Repeat Yourself). Next, it decouples the user and the user's time zone from the actual functionality of converting the times (Single Responsibility Principle) so that I can test it in isolation but I also don't have to concern myself with where that time zone is coming from. Finally, this gives me a convenient place to hook date formatting into my application when I need to. Remember, I can't just user DateTime.Parse because I don't know if 04/05/2008 means April 5th or May 4th without having some sort of cultural info associated with this. If I store the user's culture somewhere and have a similar repository, I can then combine this object with the DateTime parsing and formatting commands and create one unified DateTimeService for my application where a Date string goes in and a DateTime comes out (works the other way also). It just so happens that I have another story that reads "As a user, I want to read dates and enter dates in a way that I am familiar with so that I can interperate the meaning correctly" so this is definitely going to come in handy in the future. Some other useful things that the TimeZoneInfo class has:

TimeZoneInfo.SupportsDaylightSavingTime - this property returns a bool that is true if there is a daylight savings time on that instance of TimeZoneInfo. For Pacific Time, this would return true, for Arizona time it would return false.

TimeZoneInfo.DaylightName - this property returns the name of the Daylight Savings Time Zone, so for Pacific time it would return "Pacific Daylight Time"

TimeZoneInfo.Local - this static property returns a TimeZoneInfo class that reflects whatever the computer you're running it on is set to.

TimeZoneInfo.Utc - static property that returns a TimeZoneInfo class that is set to UTC time

TimeZoneInfo.IsDaylightSavingsTime(DateTime) - instance method that tells you if a particular datetime occurs within daylight savings time for that time zone

Anyway, this is my first exposure to having to deal with this stuff and it's convenient that .Net provides some good functionality for dealing with it easily. If you want more info, there's a number of MSDN articles on the TimeZoneInfo class and how to deal with Dates and Times in general that you can read but this post has enough info to get you started.

Alt .Net meeting- why do only developers attend?

At every Alt .Net event I've been to (all three of them but I'm still kinda new to this) as well as every conference, it seems like the vast majority of the attendees are developers. While we're there, we have sessions on things like "how to convince project managers to use Agile" and "how to talk to business people" and stuff like that. Then we return to our jobs and try to convince these people that we're right or that code quality is important or that unit tests help improve your product or other things that are obvious to us (especially after two hours of discussion). So here's my question:

WHY DON'T THE BUSINESS PEOPLE ATTEND OUR CONFERENCES?????

whoa, I just had an epiphany:

WHY DON'T WE SOFTWARE PEOPLE ATTEND THE BUSINESS CONFERENCES????

It seems like we're trying to figure out how to communicate with the "other side" that is the business. We are saying that we value communication, engagement, and people over process, however all we're doing is creating a process for trying to communicate with them. Isn't this a violation of our own principles? Certainly seems like it to me.

It works both ways, people

Instead of just talking to each other about how we communicate with the business people (and I assume the MBA conference probably has similar ideas about talking to software people), why don't we practice what we preach and bring some of these business people to our conferences and directly engage them in this whole communication thing? We can tell them how we communicate and what our needs are and what is important to us and most importantly, why these things are important. In turn, they can tell us the same thing from their perspective. I think that this would be infinitely superior to what we do now.

If you build it, they will come (and they've built it and we're sitting around)

On the flip side of this, how many of us developers actually attend any business-oriented conferences? Have any of us? What about presenting a session at them? Anyone do that? I certainly haven't and I have only myself to blame for this. I think it's time for us as a community to take action and not only bring the business folks and managers into our movement, but actively reach out to them and approach them in their community as well and let them bring us into their world for a change. Anyone out there agree with me? Anyone have any ideas on how we can do this?

Wednesday, June 25, 2008

New Job!

I'm excited to announce that I have a new job working at Microsoft! I will be on the networking team of the Core Operating Systems Division and I will be working on System.Net in the .Net framework. I'm really excited about this position as it will give me a chance to learn a lot of new things and to grow as a developer. I'd just like to thank everyone at Microsoft that I've worked with so far, especially my recruiter who has been very helpful and infinitely patient with my constant stream of questions. I'd also like to thank JP Boodhoo for his blog post which helped me to make this decision. He is absolutely right about setting goals and making sure that you're constantly raising the bar so that you are continuously improving yourself. If you don't have any goals for your life, career, family, and anything else that is important to you, then drop what you're doing and set some. There are some things that you can't change, however you can always change yourself and your situation if you make enough effort.

Monday, June 16, 2008

How I made it faster- the yearly windows reinstall

Every year my computer starts behaving very strangely. Programs get really slow, the start menu takes forever to load, the OS crashes randomly, and other strange things happen. This year's strangest thing was that for reasons unknown, Visual Studio decided that Notepad++ was my default web browser every time I launched a web application. I have no idea how this happened and it has defied my efforts to fix it. As a result, I find it easier to just reinstall windows and everything else from scratch. This usually takes me two days to get everything the way I like it, which is much less time than it usually takes me to go through and fix everything (if I even can fix everything, and yes, I have timed this). This time around, I decided to change things a bit and I've noticed that some things are much faster.

Visual Studio
I develop web applications in C#. That's really all I do at work (besides read blogs and drink coffee). Therefore, when Visual Studio prompted me to do the "common" install, I hit "custom" for the first time ever. I then got rid of everything that wasn't C# and web application related. No C++, no C++ diagnostic tools, no VB, no installation packager or whatever it is, just C# and web stuff. I also got rid of things that I never use like the icons and other crap packages. I also gave up any plugins that I don't directly use. I just started using my fresh Visual Studio install, and this thing flies now. It loads really, really fast. It still takes forever to load my solution (it has 14 projects in it, but I promised that I wouldn't complain about my project setup in this post, and no, I wasn't the one who added those projects) but everything else is fast. I also have several plugins turned on, including ReSharper, CodeIt.Right (like FxCop but useful), and the TeamCity personal build thing. Also, unlike my previous computer, I only have one version of Visual Studio installed (2008) as opposed to four versions (I used to need all four of them too).

Sql Server
Again, the only thing I care about in Sql Server is the database and the client tools. I don't use Reporting Services, Business Intelligence, the legacy DTS stuff, or any of that extra crap. I don't need it at this time. So I hit "custom installation" again and chose only those components that I actually use. I also found that I no longer need Oracle to be installed locally so I don't have that installed either, although I doubt this is speeding things up any because I had it turned off unless I was actively using it.

Other Software
So before I started randomly installing all the stuff from Hanselman's tool list, I made a list of all the software installed on my old computer. I then started crossing out things that I can't remember using in the last six months. I installed what was left, including Launchy, Nant, NUnit (sorry MbUnit, but some people at my work don't like you so I can't use you anymore. . . at work), DisplayFusion, ReSharper, Firefox, Subversion, and Notepad++. So far, I have yet to find something that I miss. Please also note that I didn't install Tortoise SVN this time around, which brings us to the next most useful thing that I installed:

Cygwin!!!!!!11!11!1!1!!one!11!!
I love this thing. It basically gives me a Bash shell on windows. It has all the unix commands that I'm used to using. It has alias and ln. It has hundreds of packages, including subversion. It's find totally pwns windows find. It has grep so I can do something like alias devenv=`find / -name devenve.exe | grep devenv.exe` and I get to type "devenv" and it launches Visual Studio without me having to fuck around with my Path or other environment variables. I also have vi and nano, which rule (I use nano when I need to change one stupid line of a config file because I find it simpler to use for that purpose than vi, but vi is for anything more complex). I have only begun to figure out the coolness that is Cygwin. I also get Python and Perl and probably Ruby, although I haven't actually looked for a Ruby package yet. Be warned, however: If you are not familiar with Unix, including commands, the file system, and concepts like fork(), it probably is not for you. Also, when you want to launch a program and not have the shell sit there and wait for the program to terminate, the correct thing is to add a '&' to the end of the line, i.e. /devenv.exe &
will launch Visual Studio and kick it into the background so I can do other stuff with the shell.

The results

My computer loads faster. A lot faster. This is probably due to a combination of factors, but I would say the biggest difference between this computer and the last is Sql Server only has two services running now instead of like 1000 or something (I'm exaggerating but you get the idea). I also don't have Tortoise slowing explorer down, although I may reinstall it if I find that I'm not more productive using svn from the command line. Visual studio starts faster. I also don't have to worry about which version of Visual Studio launchy decides to launch for me either. It also stops faster when I close it.

The moral of the story:

The moral here is really stupidly obvious: Don't install crap that you don't use or need. This really shouldn't need to be said, but I find that a lot of people just hit "default install" when they shouldn't be. They also install crap that they don't use and don't need. That being said, may I present:

Jeff's guide to the obvious: Volume 1
  1. Always use custom install when installing software. Pick only what you need. This applies to everything.
  2. You can always run setup again if you need to add something.
  3. Don't just install something because it "looks like you might use it"
  4. Any software that you don't use in more than six months, get rid of it.
  5. Any software that you don't immediately start to love and use frequently, get rid of it
  6. Don't just install everything off of Hanselman's tools list (uh, not that I ever did or anything. . . . )
Follow these simple instructions and I guarantee your computer will run faster and have less random behavior, although having Notepad++ be your default browser is useful sometimes.

Seattle Alt.Net open spaces

There was an open spaces event for the Seattle Alt .Net community on May 24th (I know, this post has been sitting around for a while just be glad I have insomnia tonight). I think I learn more in these open spaces events than anything else I've been to so my first advice is to find (or start) a local group and have these things.

Everyone has something to contribute

I think it was Dave Laribee (please correct me if I'm wrong) who said that "everyone here is a leader" at the last open spaces I went to. This is absolutely true. I find that everyone, no matter who they are, what their experience is, or what they work on, has something meaningful to say on something. That's one of the things I really like about these events.

The event

So this open spaces was at the offices of Lexis Nexis so I would like to publicly thank them for generously donating their space and providing lunch. Employer support of Alt .Net and these types of events is critical in ensuring that they happen and that the are accessible to all. I hope that everyone's company will follow Lexis Nexis' lead in supporting these types of events as they directly contribute to the education of their developers, and a company with good developers is more likely to be successful and deliver a better product.

We discussed a number of things at the event, most of which we were able to video, so I'm not going to spend a bunch of time recapping, however I will come back and edit this post with the links to the videos once they're are available.

The biggest thing that we got out of this event was a good foundation for a Seattle Alt .Net community. It turns out that there are a lot of us devs out there, definitely more than I had suspected, that are interested in this whole Alt .Net thing. In fact, it's looking like our open spaces is going to be a monthly thing (last I heard we're going for the fourth Saturday of the month) so I'm excited about seeing where this is going to go. If you are interested (you should be) you should subscribe to our google group and start coming to these things. Remember, everyone is welcome and everyone has something to contribute. Seriously, you should come to our next event. Even if you disagree with everything Alt .Net is, come out anyway and see what we're all about (and if you do disagree with everything, by all means share your opinions because maybe you've thought of something that none of us have).

The next event will be on June 28th at:

Mantis Technology Group, Inc.
12413 Willows Road NE
Suite 300
Kirkland, WA 98034

I'll see you there!

Wednesday, May 28, 2008

Why Elegant Code doesn't get Agile

This blog post seems to insinuate that Agile does not work. I believe that their David Starr (correction: I directed this at all of Elegant Code when I should have been specific to the poster. Apologies for this oversight on my part) conclusions are flawed and that they truly don't understand that Agile is an idea and not a process. I think a better title of this post would be "why being dogmatic about Agile doesn't really work" or "why people who do things because that's what you do in Scrum doesn't really work" or some such. By making this blanket statement about Agile not working, they are both ignoring the many success stories that Agile has and betraying their own ignorance of the Agile process.
"Agile supports the idea of frequent delivery of value to customers."

Let's look at shipping software for a minute. Where in the Agile Manifesto does it say "You have to ship software every two weeks" or anything like that? Go ahead, look for it. I'll wait. Didn't find it? That's because it isn't there, and it isn't there for a reason. That reason (I generally believe) is that shipping software to customers every two weeks is a retarded-stupid idea for all of the reasons that the article goes into. I'll summarize them here:
  • Sales can't keep up with that release cycle
  • Training can't keep up with that release cycle
  • Documentation is often not available at that frequency
I'll even add a few more:
  • Any type of release-preparation can't be done (burning CD's, peer-review, post-mortems, etc)
  • Software with a high amount of overhead to upgrade won't allow for this (think SAP or Sharepoint or some such product)
  • Most customers don't want a new version every two weeks because they'll have to upgrade and re-train their employees
  • This pace is not sustainable, which is something that is, in fact, on the Agile Manifesto ("Agile process promote sustainable development")
So what's the point? In Agile, we recognize that working software is the best measure of productivity. We also recognize that we want to deliver working software as frequently as possible. This brings us to:

DELIVERING WORKING SOFTWARE IS NOT THE SAME AS SHIPPING A PRODUCT!!!!!!!!!!!!!!!!!

That's right, you can deliver working code constantly. You can deliver it to sales so that they can preview what they're going to sell. You can deliver it to your customer proxy to verify that you have correctly implemented the features that you need. You can deliver it to your sprint demo so that the rest of the world can see it work and know that you're going well. You can deliver it to your project manager so that he doesn't have a heart attack every sprint because the software doesn't work. BUT YOU DON'T HAVE TO SHIP IT. Just because you CAN ship something doesn't mean that you should.

So why do we deliver working code in the first place if we're not going to ship it?

Because in Agile, we want rapid feedback. It is much, much easier to fix something right after you build it than it is to fix it three months after you build it. The sooner you know that you need to change something, the easier it is. For example, let's say that your QA department is one sprint behind your development in their testing. On my team, we average about ten builds per day (utilizing our CI tools at the time of checkin, but if you count personal builds it's probably a lot more). Our sprint is three weeks, which gives us about 14 days of development on average (adjusted for the time spent on code review, sprint planning, sprint demos, holidays, etc.). With ten builds per day, that means at a minimum, QA is finding a bug that has existed for 140 builds. Other functionality may be built on top of it. It may have dependencies on other parts of your code. Finally, where the hell is that bug occurring, given that maybe you've worked on a dozen different objects since the bug was introduced? You'll have to hunt for it, and that takes time.

So Elegant Code has missed the boat on this one: They're assuming that delivering working software means "shipping it to the customer" when this is absolutely not the case. They're jumping to that conclusion. Maybe I should write "delivering software means shipping it to the customer" on a mat on the floor, and they could "jump" to it. I'll make a million dollars!

"[The] organization [you're shipping to] must actually be able to receive the update without tipping over"

This is their second argument against Agile, and (coincidentally enough) their second mistake. I've added some words to clarify their point so that it isn't taken out of context, but I would encourage you to read the article so that you don't think I'm making this up. That is not my intent. Anyway, we aren't shipping the software every two weeks, so the customer only gets their release when they actually want it. The strength of Agile is twofold on this:
  1. We can show them what they're going to get more easily because the software is always working. We can give them a beta whenever they're ready for it so they can start coding against our API if they want to. If they don't like our API, we can change it easily and ship a new version. They can see if the features they want are actually going to work the way they want. They can give us rapid feedback, which is very important to our ability to deliver them the features that they want.
  2. We don't have to ship it to them "on time" either, because when you can ship every two weeks, "on time" starts to mean whatever you want it to mean. If they aren't ready for a month or two, we can delay and continue to add value (or just branch the code) and ship when they're ready to receive. If they suddenly get an upgrade to their database and our code is going to break it if we add Oracle support, we can release a working version prior to adding Oracle support. BizTalk no longer supports a feature? Prioritize that as a sprint item and ship two weeks later. Try doing that in waterfall.
In short, we gain a lot of flexibility over when we can ship. Again they're leaping to a conclusion (maybe two spaces on the mat and they can "jump" to both "conclusions") that they have to ship and it'll cause all kinds of problems for the customer if they do. In fact, the opposite is true: because you can ship at any time, you have the flexibility to deliver value whenever it is best for the customer. If you force them to upgrade, that's really an anti-pattern that I call "shoving functionality down their throats until they choke on it." This is never good.

In fact, the problems that they describe are actually readily solved by Agility: Documentation team needs another week or two? No problem. At least we have a working piece of software for them to document against. We either add something small that they can easily document, refactor the code against our //TODO list, or branch and keep going with the intent to release a branch. IT says you need a week-long burn in test? Or what about a month long peer-review process like my company? Not a problem either, we just branch and continue working on the trunk, fixing anything that comes up in the branch (which is what we're releasing) and merge those fixes with the trunk one at a time as soon as they're finished so that integration is easier.

Ultimately, Elegant Code David Starr has not missed the boat, but unfortunately the boat that they caught was the failboat. Their argument sounds good on the surface, but they have failed to realize that Agile's ability to handle change combined with a rapid feedback cycle actually deals quite nicely with all the problems that they are describing. I'd like to close with a question: If Agile doesn't work, what does? Huh? Can't find that in the article? It's in the same place in the article as "shipping software" is in the Agile Manifesto (i.e. it's not there). I think Elegant Code needs to do some more studying on what Agile is and what it truly means, as well as looking at some success and failure stories before they suggest that Agile has failed because you can ship too frequently if you're dogmatic about it.