pioneering outsourcing 2.0
12  01 2008

YAGNI : You Aren’t Gonna Neet It

In our previous post on Set based Concurrent Engineering and Software, we discussed how the trick in Set based Concurrent Engineering (SBCE), is to realize what decisions you can defer and what you must take now as well as how risky or difficult would it be to change a decision later. We also discussed how good design should keep options open, and how this in turn helps us to be flexible and quick to respond to challenges. One approach that many people use [in Agile, Lean and even Waterfall] is You Aren’t Gonna Need It. Like other aspects of Agile and Lean, the concept is simple. Yet, understanding and implementing it can be very difficult. This is because, the concept is against the traditional way. In this case, foreseeing and predicting the future and planning for it has been considered the hallmark of great teams. However, the concept of YAGNI and Do The Simplest Thing That Can Work (DTSTTCW), suggest that its not as much foresight of what will happen in future, but ability to respond effectively to what will happen that separates the really good teams from the average ones. In terms of software, we have always tried to design for “any and all eventualities“, while following practices that do the exact reverse. This is because, we are not designing the architecture for “any and all eventualities” but what we consider to be “any and all eventualities“. If the events unfold exactly the way we want them to, everything goes nicely. The moment there is a deviation, things go astray. In contrast with this elaborate Big Design Up Front, sometimes deferring a decision making to when you have enough information is the best thing to do.

YAGNI is a XP practice which states that “Always implement things when you actually need them, never when you just foresee that you need them.” XP actually takes it a step further and says that even if you’re totally, totally, totally sure that you’ll need a feature later on, don’t implement it now. However, to start with if you have any doubt about “whether you will need it” you should not add that feature. This is because you *might* need the feature in future, but you *might not* either, even if you are very sure right now. If you build the feature, only to discard it later - it would be waste of effort. You might actually need the feature and implement it, but you might need it in a different format and hence, would need to do some work to add to it anyways. Some other disadvantages of doing “what is not needed right now”, right now are:

  • The time spent is taken from adding, testing or improving necessary functionality
  • The new features must be debugged, documented, and supported
  • Any new feature imposes constraints on what can be done in the future, so an unnecessary feature now may prevent implementing a necessary feature later
  • Until the feature is actually needed it is difficult to fully define what it should do and to test it. If the new feature is not properly defined and tested, the unnecessary feature may not work right, even if it eventually is needed
  • The software becomes larger and more complicated
  • Adding the new feature may suggest other new features. If these new features are implemented as well, this may result in a situation where you don’t know where to draw a line

As you can see the above are pretty serious issues. And we take them on in a software architecture/ project on the *promise* and *premise* that it would be useful down the road.

The above said, you can religiously follow the letter of YAGNI and yet miss the spirit of YAGNI. The idea of YAGNI is not only to not commit to decisions as late as possible but also do the minimal that could work now. If following YAGNI means that you are actually doing more work “now”, you are not following the spirit of YAGNI. Similarly, the idea of YAGNI is to keep the code simple. If doing “YAGNI” makes your code more complex, you are not following the spirit of YAGNI. For instance, committing to a database is a big decision and you would like to keep the decision open till as late as you can. However, if you already have a database persistence mechanism, not using the same and writing your own file based implementation simply because your feature “does not need it”, would only add chaos. Although, your feature does not need it and probably the feature would take more time using the database persistent mechanism but maintaining two sets of persistent mechanism has two different implementations for same work. We said that “YAGNI is simple” yet “it can be difficult to implement”. For instance, “You aren’t gonna need it” is not about making a method private because “no one will use it, never”. It’s about not putting a pluggable generic templating mechanism for different kind of outputs if your requirement just state “show static HTML”. It does not ask you to be lazy or stop thinking about a requirement. It asks you to consider if you “really need” to write you code in this way or you can simplify it can use it only for the purpose of “this requirement”. The difference is enormous.

Some of the arguments against YAGNI have been that sometimes you have to implement a certain feature, you should factor in that at present. Everything has a cost of doing right now and also the cost for not doing it right now. If the ratio is high, it would be a waste to do these features right now. If the ratio is low [i.e. cost of not doing it now is high], then in all likelihood, the requirements should be prioritized and clear your way in doing something right now. So, lets say you talk to your customer and conversation goes like this:

  • Team: We see you have this requirement down in iteration 2. We think that this requirement we are doing in this iteration should factor in that requirement as well and if we took a bit of time to define the interfaces well, we would save a bit of time in iteration 2.
  • Customer: Ok, how much time would you save?
  • Team: Umn! Maybe 4 hours.
  • Customer: And you will need to write that interface anyways?
  • Team: Yes.
  • Customer: Good! Tell me, if I chose not to implement this feature in iteration 2 but iteration 6, but pick these apparently related requirement from iteration 3 in iteration 2, would the work you do still be useful.
  • Team: Umn! Probably yes!
  • Customer: So can you code in a way that all the requirements in future iterations are taken care of right now because I don’t know what might need to be done when. Maybe, iteration 2 is pretty stable but not so sure about iteration 3 onwards.
  • Team: Yes, we can. We can simply code for iteration 1 right now and not commit either to iteration 6 or 2 feature requirements right now
  • Customer: Cool! Would that be YAGNI?
  • Team: Err, Yeah!

This is a slightly simplified example, but the crux is that if something has this huge advantage of doing right now, then it should be a priority anyways. The above conversation could probably end with customer asking the team to do it now if the question the team posed was, “whether we should write the comments as we go or later” or “can we commit to a coding architecture right now”. This is often presented in what is called “Opportunity Cost Argument” i.e. loss of cost from other opportunities by choosing to go with only one opportunity. This can be balanced by sometimes asking “what is the cost of not choosing this opportunity right now”.

YAGNI is not a standalone concept and must be used with common sense and following good design principles, good testing framework and continuous refactoring. We like to think of YAGNI as a question and not the answer. The answer has to be provided by you. The secret is to use your brain and not reply on the letter of what the concept says but the spirit as well. This is where Agile separates itself from other processes anyways. The concept does not ask you to be blind. It only asks you to be not be a soothsayer.

Popularity: 29%

28  12 2007

Outsourcing and Business Value - The Scrum Context

Modern organizations work in a large horizontal and vertical network comprising of entities who interact [pass information or material or capital] with each other. Optimizing one relationship without considering the effect of the same on the overall system, can lead to lower and sub-optimal business value. One example of such a sub-optimal step includes stocking vast piles of inventory leading to massive increase in storage costs and loss of stored material, where considering this entity from a systems thinking perspective led to growth of Just in Time Inventory Control. “Outsource to cheap vendor” is one such sub-optimal step an organization could take. Cutting costs is a useful goal for an organization to focus on but is probably not the only goal the organization should focus on. Other goals to focus on could generally include quality, faster time to market, responsiveness to change, flexibility, competitive advantage. While deciding to outsource work, an organization would want the business value to be optimized across the value chain rather than just cut costs.

However, optimizing business value across a value chain, a difficult goal even if all work is done in a single organization, is especially difficult when the value chain includes more than one organization [which is the case when you outsource]. Generally, within the organization, each department is trying to maximize its own individual measurements. This gets magnified within an outsourcing environment where each organization is trying to extract the maximum pound of flesh from the deal as possible. The pound of flesh is generally defined and tracked by individual measurements in each organization. For instance, the firm outsourcing the work negotiates on the lowest price possible while the vendor is typically looking to not exceed the price while developing the project. As is obvious, these measurements do not span the value chain and will invariably [particularly if the products are critical, large or in demand] cause sub-optimized business value across the organizations. In the above example, none of the two organizations is actually focusing on “getting the right product to the market in the right time” and the “overall business value” has not been defined specifically. Rather, a contractual document with clauses and clauses to define the “terms of engagement” is generally put in place between two companies. The immediate fall out of contracts is to cause measurements and controls such as cost, schedule and scope. It is also assumed that meeting the contract terms is equivalent to providing business value. This is often misguided thinking. A collaboration is successful if it provides something useful and not because it delivered something thats “within scope, within cost and on time”. Cost and time are important parameters but already considered within “something useful” [something spiraling out of cost or time would rarely be useful]. Hence, cost - schedule - scope triangle does not define business value. Rather, such measurement will mostly get in the way of driving the effort toward true business value. The fundamental focus should be to do away with sub-optimizing points of measurement so as to optimize business value across multiple companies.

If cost, scope and time do not define business value - then it is logical to ask what would. In software, we generally consider value to be defined as function of features, quality, time and cost. Within this paradigm, it has to be noted that true business value would be more dependent on features and quality, and often not on meeting *tight* deadlines and rarely on meeting *tight* cost targets. The distinction between deadlines and costs being “exceeded by a distance” and “not being met” is subtle but important. The most important aspect in the business value as per the parameters above are the features. Features embody “what is being built“, “what is the business case“, “risk associated in not developing” etc. Sometimes, there would be a risk for not “doing by a date” and very often for “not being up to mark on the quality“. The fact that we keep features, quality, time and cost as parameters reflects their dynamic nature. These change because:

  • What was thought nice to develop today, might be outdated or too risky tomorrow
  • What was the priority today might not be a priority tomorrow
  • Some new features might be discovered
  • Some new standards of quality might need to be adhered to
  • Timelines might be important today but not tomorrow
  • We might have cost surplus today but not tomorrow

Based on the above, another dimension needs to be added to define business value in these dynamic times. We can call it “flexibility” or “responsiveness to change“.

Hence, business value at its very least for today’s “terms of engagement” has to focus as a function of features, quality, time, cost and flexibility. Most Scrum teams [and Agile teams as well] pride themselves in delivering business value faster and regularly. Business Value operates at multiple levels through simple means in Scrum. For instance, prioritized backlog allows delivery of high priority features first. Product Owners usually decide the priority by balancing risk and opportunity. Focusing on risk allows early feedback and course correction. This reduces the risk of developing wrong features or wrong product itself. The development people [which could be outsourced offshore] and the business people work as one team on prioritized features. Further, the measurement for business side is on prioritizing the features to be developed and explain business case and acceptance criteria along with evaluating/ providing feedback on developed features. The measurement for development side is to develop highest priority features and incorporate change. In addition, the review of the priorities and work done as per the priorities is held at the end of each iteration, which is usually only a few weeks. Ruthless prioritization of the features to be developed along with a strong inspection and adaptation framework creates a flexible, self correcting and highly transparent mechanism for engagement between both sides.

Popularity: 33%