Sunday, March 8, 2009

YAGNI Abuse

YAGNI "You Ain't Gonna Need It" is one of those principles I usually say I hate.  Truthfully, I suppose I don't hate the YAGNI principle, I think I typically hate when people try to pull it out in a discussion/argument.  I feel that sometimes people use YAGNI either as an excuse to write poor code or as an excuse for why they don't need to improve as a developer.

Somewhat recently, Jeremy Miller wrote a post titled "A Quck Example of YAGNI / Simplest Thing Possible In Action" which completely annoyed me.  I think it got under my skin so much because of how highly I view Jeremy.  I spoke with some people after a recent Great Lakes Area .Net User Group meeting about this.  To be fair, after that post and after my discussions Jeremy did make a second post titled "Update on the YAGNI Episode" where he explains that he was wrong in the prior post.  I probably should have written this post earlier.

In Jeremy's original post he discusses an argument he had with another member of his team regarding how to build a simple web layout which included a 2x2 arrangement of panels which will hold various content.  Jeremy uses YAGNI to argue that this layout should be done using an HTML table with 2 rows and 2 columns.  It's relatively simple, it works, why try to complicate things?  He argued that this was the simplest thing to do which would satisfy the current requirement.

To me, this shows that Jeremy is not an expert at HTML design, and was trying to use YAGNI to defend it.  I think there should be a new principle for Jeremy, and for others trying to use YAGNI.  Let's call it "Use What You Know".  Maybe we could call it WYK or something like that.  Jeremy knows how to lay out web sites using tables.  If he's working on a project where he needs to lay out panels, that's probably what he should do.  However, in cases where someone else on the team understands a superior approach which allows more flexibility to be replaced in the future, that's what they should use.

To me, YAGNI needs to be about features, not the technical approach.  The technical approach needs to be clean and easily replaceable.  This is a big reason why I'm such a big fan of the Single Responsibility, Open-Closed and the Inversion of Control principles.  When used correctly these principles, not meaning to exclude many other solid principles, result in maintainable and easily replaceable code.  Code which follows these principles is not necessarily hard to write (sometimes it does involve some different ways of thinking), and it doesn't typically take any more time, but the benefits really pay off when you actually do "Need It" and have to change a piece of your software.  In cases before I have written extremely simple services which work for the current functionality only to require that they be fully replaced with more advanced functionality in the future.  This is fine, simply swapping out that service for the newer service was a simple switch which didn't require breaking the rest of the application.

That's how YAGNI should be used.  Only build the functionality that you need, but leave it easy to enhance or even replace. 

In many cases I feel that developers use arguments against Inversion of Control, or the Open-Closed principle because of YAGNI.  They argue you don't need that flexibility.  You don't need to replace your services easily.  It's a simple application, it works without it, why are you pushing this?  To me that's using YAGNI to fight continuous improvement.  As developers we should strive to constantly hone our craft.  We should always look to find ways to better do our job.  It's the same argument I make all the time.  Doing things the "clean" way is usually not more work, or more time consuming than the "quick and dirty" way.  However, not understanding how to do it cleanly, does result in it being significantly easier and faster to do things the "quick and dirty" way.

Getting back to the "Use What You Know" point.  I'm not advocating that every time a problem comes up you research what the cleanest way is to do it.  I'm advocating that you find time to learn about new approaches to solving software development problems before you have to use it on the job.  The employer typically requires fast turn around on the software problems you face.  Deliver the solution that you know how to deliver.  That gives the employer or customer the solution that works the fastest and for the least cost.  However, if we could have spent earlier months learning new techniques and solutions, the employer could receive superior products while developers are able to enjoy working on a cleaner code base.

Ideally you find employers that allow for time up front for you to lean and continuously improve.  That way when the problem comes you are better suited to solve it with a larger toolbox.  Some employers do not allow time for this, and instead developers are forced to improve on their own time.  Regardless, I would advocate that we all put in the extra effort to learn on our own time.  The ones with employers that pay for this time are lucky, but that doesn't let the rest of us off the hook.

Tuesday, March 3, 2009

Spoke at GANG

I finally gave my talk at GANG.  I was originally scheduled to speak in September (Speaking at GANG), but came down with food poisoning which prevented me from talking.  That same talk, an Introduction to Rhino Mocks, was made last month in February.

 

I really enjoyed giving the talk.  The crowd was great, and overall I had a good time.  I hope others enjoyed the talk and were able to learn about how Rhino Mocks may come in handy with their software testing needs.

 

At the end of the talk I said I would post my example application online.  I have decided to place the file on savefile.com.  You will have to put up with an ad in order to download the file.  Download the sample here.

 

In the near future, I plan to post in detail about some parts of the application application.  If readers would like an explanation of any piece in particular, please leave a comment on this post.

Blogger Syntax Highliter