YAGNI! .. Or are you?!

by Jon Davis 25. August 2008 05:41

SD Times recently published survey results of the question, "What practicies do you consider most essential during software construction?", with these top 5 rankings (answers are ranked in levels of importance on a scale of 1 to 5):

  1. Emphasis on functioning code (YAGNI) (4.18)
  2. Unit-testing (4.14)
  3. Continuous integration (4.13)
  4. Delivery cycle 2 months or less (3.91)
  5. Emphasis on code aesthetics (3.72)

Surprisingly, code aesthetics beat out code reviews, dedicated QA staff, even language choice. 

One philosphy I have a problem with is YAGNI ("You Ain't Gonna Need It!"), which is basically the rule that if it's not required, don't add it. But now let me clarify my frustration. It isn't with the principle of not adding code you don't need. I agree with the principle of avoiding unneeded bloat and weight and garbage code in a codebase by never implementing things you don't need.

I got inspired to post this blog entry after reading someone's blog entry and its comments that I agree with on the topic, to detail:
http://blog.qualityaspect.com/2006/06/10/the-semi-myth-of-yagni/

My issue is with the verbiage of the acronym and what brainwashing it has done to people. It's a terribly broad and unqualified statement, and it's also unacceptably presumptuous. It shows that YAGNI is apparently meant only for actual software construction with tight, documented requirements, not continuous development and engineering such as maintaining and growing a web site or an IT system. Otherwise, just because an idea pops into a developer's head doesn't mean you're not going to need it. My own code tends to get a little bit large but that's because I evaluate, reevaluate, and reevaluate again what's required to make an implementation bug-free. I test my own code and expand as needed. More often than not, bugs are the absence of needed internal features that were not included during the design phase. Technically, every line of code is a seperate "feature" of a routine. For example, invoking a clean-up routine is a "feaure", but don't tell me it wasn't needed just because we forgot to consider it in the requirements.

Usually the explanation of YAGNI goes something like, "If you came up with a cool method or routine or event or event handler that you want to put on the object, but it wasn't a part of the requirements, do not add it, period! Even if you have plans to use it, unless it's a part of the requirements, do not add it!" I agree with it to an extent; extensive unnecessary code is and results in waste -- waste of time, energy, and, in the long run, money. The problem is that the requirements do not always consider the scope of the implementation. Sometimes the implementation introduces additional requirements, or additional requirements get introduced during the discussion of implementation. For example, "Send this object over the wire to that service and have it send this other object back." Is there only one class of this object? Do you want exactly 2 class forms / interfaces / contracts to be sent and received? Or, do you want to package the class into a generic data transfer contract instead?

And sometimes features are desirable for the sakes of reusability and flexability. A lot of my concern boils down to two architecture-affecting developers (i.e. myself and another) not agreeing on what they're going to use a software component for. My argument is that the objects being sent over the wire should be generic DTO contracts of dictionary-like structures, sent using WCF, rather than strongly typed class serializations over Remoting. The other individual argued that their use is the only use intended for this component, and that my intentions of reusing it on other things are beyond the scope of development. "You're designing for the unplanned future." But I had big plans, indeed. In the end, my broad-based reusable scenario was the one that was implemented, and it was implemented successfully and deployed successfully, and the scenario-specific implementation never even happened, primarily due to the other person's protest of the whole situation, insisting YAGNI. And, yes, my codebase was large. But it proved worth it when it was deployed all over the place for many projects. We were one management decision short of open-sourcing the client-server component as a one-of-a-kind solution for the .NET community, in which case it could have been used not just on several of our projects but all over the world, too. (There was one lingering bug we had a hard time tracking down but it had little to nothing to do with my genericization--and lots to do with the other individual's refusal to jump in and be a part of the component's upkeep while I was on it.)

In the short term, spreading out beyond the initial requirements slowed us all down. But in the long run, we had one reusable codebase to support them all, which was much easier to manage across multiple projects than strongly typed transfer over Remoting. Had we coded for the specific requirements, imagine strongly typed transfer code, reproduced over and over again each time a new set of requirements came, each time with a different coding style, each time with a different set of potential bugs. For that matter, we wouldn't have implemented the feature at in other solutions at all because we had nothing to reuse except proof of practice. Agile would prove to not be agile enough. Needless to say, I'm fast losing interest in Agile methodology and philosophy, as I'm a huge believer in making large short-term investments for long-term futures. True agility to me is in building tools and reusable components. But software built as such is not easily billable; Agile developers want to account for their every effort each time. Their philosophy seems to be to waste no time but lose no billable hour to prebuilt work.

Now then, someone blogged about the YAGNI scenario of one developer wanting to use BizTalk to fetch a file for processing, while another wanted to use WebClient. The latter won the YAGNI argument, I guess. But my questions might be, "Is BizTalk already used in the solution? Does it already perform similar fetches for processing?" I'm obviously appreciative of going lightweight, in general. This is an extreme scenario, you can't get much lighter weight than WebClient, and in a solution that doesn't have BizTalk already I'd say just use WebClient, too. But if there are business protocols that can kept in check by BizTalk then don't throw consideration of BizTalk out, and certainly be careful about using multiple mechanisms for the same functionality.

These things said, I'll nod in agreement that if a new feature is literally a new feature, and not a dependency feature in order to round out the completeness of the implementation of a broad requirement, don't implement it in the production codebase; it's a prototype. Treat it as prototype code--work on it in your spare time, and put it in a seperate project that has the word "prototype" in the project name. If you really love the idea, present it to the manager / designer / architect to see if it should be added; if not, shelf it, maybe it will come in handy later. But don't put it in the production codebase.

I think the better philosphies over YAGNI are to Be Intentional and Plan For Reuse. Everything should have a reason and a purpose. If you're going to add code, be prepared to argue for it, test it, document it, or whatever else needs doing, and ask yourself, "Is it worth it? Or should I find a cheaper workaround?" Planning for reuse, meanwhile, means that lightweight adjustments and additions are called for if a component can be reused elsewhere but still pass all current requirements, as long as the time and effort to reuse the component is extremely simple from that point on, and you have absolute cases for reuse (you're not hoping something might come up later).

In my opinion, many developers especially at the senior level are also decision-makers at the finer levels of detail, and as decision makers they must often make such decisions as, "We actually do need this new feature because I actually will be needing to use it next month and I really won't have time to implement it at that time." Now if that gets backed up with just saying, "I'm in the zone in this module right now and I don't want to lose what I have in mind," I might acknowledge it might be best to call it prototype code and to export and remove it from production code after some satisfying implementation and testing are done. However, the point I am trying to make is that sometimes the developer is right, and the requirements fell short. I suppose in a cranky corporate environment the developer would need to seek permission for the feature to be added by way of adding the feature to the requirements. But if the interest is in getting the job done quickly with minimal overhead and bloat, I'd suggest to just sneak it in and apologize and explain yourself later. Again, be intentional, and be able to back up your actions with reason. The saying, "Rules are meant to be broken," fits like a glove with YAGNI. (But you'd better be right about your violations, and have authority to do the violating.)

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags:

Software Development

Add comment


(Will show your Gravatar icon)  

  Country flag

biuquote
  • Comment
  • Preview
Loading




 

Powered by BlogEngine.NET 1.4.5.0
Theme by Mads Kristensen

About the author

Jon Davis (aka "stimpy77") has been a programmer, developer, and consultant for web and Windows software solutions professionally since 1997, with experience ranging from OS and hardware support to DHTML programming to IIS/ASP web apps to Java network programming to Visual Basic applications to C# desktop apps.
 
Software in all forms is also his sole hobby, whether playing PC games or tinkering with programming them. "I was playing Defender on the Commodore 64," he reminisces, "when I decided at the age of 12 or so that I want to be a computer programmer when I grow up."

Jon was previously employed as a senior .NET developer at a very well-known Internet services company whom you're more likely than not to have directly done business with. However, this blog and all of jondavis.net have no affiliation with, and are not representative of, his former employer in any way.

Contact Me 


Tag cloud

Calendar

<<  October 2020  >>
MoTuWeThFrSaSu
2829301234
567891011
12131415161718
19202122232425
2627282930311
2345678

View posts in large calendar