tags:

views:

195

answers:

5

Imagine you have user story 1 which requires the implementation of a method:

public static void MyMethod(string paramA);

Several classes will be using this method, and MyMethod does everything required to complete user story 1, but nothing more.

You are pretty sure that in a future iteration another story (user story 2) will come along which will require the method to become:

public static void MyMethod(string paramA, int paramB);

The previous calls to MyMethod will need to be refactored, and some new calls to MyMethod will need to be added to meet the requirements of user story 2 (Note after story 2 it never makes sense to call MyMethod with only paramA).

When working on user story 1 is agile thinking to:

1) Only implement: public void MyMethod(string paramA);

2) Implement: public void MyMethod(string paramA, int paramB); - But do nothing with the second parameter for now. Calls pass in 0 to the second parameter at this point.

3) Implement: public void MyMethod(string paramA, int paramB); - But do nothing with the second parameter for now. Calls pass in the correct value (according to the expectation of user story 2)

4) Implement: public void MyMethod(string paramA, int paramB); - And all calls Completely to cover user story 1 and 2

A: 

With a modern development tool, refactoring the method to have a second parameter is very low cost. So implementing the first story seems to make the most sense and then revisiting the method when it comes to the later story.

However... Like all good questions the answer is really "it depends". In some respects your example is too trivial to do justice to the discussion. What if story A was "update customer name" and story B added some sort of transactional feature (maybe paramB is the TX context). In which case maybe your stories need some work. Does A make any real sense without B? Is A implemented this morning and B this afternoon, or is B work for next month?

Ade Miller
Or is B an optional param with possibly a default value.
amischiefr
Yes, I don't understand why it's not an option. It is a perfect example of why default parameters appear at the end of functions, for no-impact extension.Not wanting to bite off a Java/C# vs C++ argument about it however :)
polyglot
It's definately not an optional parameter under this scenario. It is imperative that this value is fetched and set correctly to meet user story 2. Also dont want this to be a discussion about language use, more high level Agile thinking, but I take your points.
Ben Breen
+1  A: 

The purists will say option 1, but I'd listen to common sense and if you're absolutely 100% convinced that this is a requirement then I'd factor this in to your design.

HOWEVER Agile is also heavily based around refactoring, so as long as you aren't publicly releasing this interface then I would actually go with option 1 if changing this won't impact my design.

Duncan
So in the case where this was a public API that wasn't supposed to change, then it would sense to implement for story 2 (or 3, 4...)?
Soo Wei Tan
Yeah, personally I would do that. Updating a public API once it has been released would be a world of pain. Of course, you've got to ask yourself WHY you would release the API to the public given that it was still going to change...
Duncan
+10  A: 

Just do 1.

Refactoring is easy, predicting the future isn't.

The project may be canned, new more important stories may appear that means story 2 is never needed, by the time you get to story 2 you may understand the problem better and need to refactor everything. There are endless reasons you mightn't need it.

Pablojim
+1 for the YAGNI approach
Jacob
+1. YAGNI. This is an extreme example but the principle is precisely correct. What if there were ten methods that might need to be refactored in story 2, maybe?
Jeremy McGee
+2  A: 

On one end of the spectrum are the Agile purists that insist that everything can be accomplished by refactoring later. On the other end are the old-school Big-Design-Up-Front crowd that think you should build a complete architecture first and then snap features onto it. Your question is perfect because it exposes the failings of both philosophies if you mindlessly follow their processes. What you want is maximum efficiency. So you need to analyze what Story 1 and Story 2 are in your situation. Is your software shippable without S2 or did you just split up the stories to help with estimating and planning? If S1 is "Add to shopping cart" and S2 is "Check-out" it is silly to not build the interface to support S2 because your software is worthless without it. In every project there is a certain set of known "Have-to-have" features that make your software even worth shipping. If Both of your stories are from that set then I would say build the interface to support both now and don't waste time refactoring later (#3).

Usually if S1 and S2 are both in the must-have set they will be close together on the Backlog. If this is not the case then you either have a huge amount of must-haves and your project isn't going to gain that much advantage using Agile techniques or S2 really isn't a must have. So if you are expecting a large chuck of time (months?) to pass between the commitment to S1 and S2, then I would go with the 1 parameter interface. Time is always a huge contributer to uncertainty.

DancesWithBamboo
I like you answer a lot. The only thing I would say is that S1 is in interation 1 and S2 is in iteration 2. I belive one should always have a shippable product at the end of every iteration. Now: After one iteration it is unlikely the business would be happy to ship the proudct, but it could certainly go to QA and be well tested. So do you aim for efficiency and do it now (but there is a small chance you'll get it wrong as requirements and/or design can change), or do only what is required for iteration 1?
Ben Breen
Also note that I do not belive in doing anything 'wrong' for iteration 1. E.g. There is no point in implementing something which will have to be entirely re-designed when story 2 comes along. If you know whats coming up that would be crazy. But should you go the extra mile in S1 so that you do minimal work when S2 comes along? Or do you favour focus, also knowing: "Prediction is very difficult, especially about the future." - Niels Bohr (Danish physicist).
Ben Breen
I wouldn't consider adding a parameter to a method that wasn't used in it in S1 to be creating an unshipable product. You might call it unnecessarily bloated, but certainly still functional. Shippable just means Done-Done; tested, documented, buildable, and installable.
DancesWithBamboo
+1  A: 

"It depends." How you answer depends largely on how disciplined your team is.

The situation you describe invites a very small step across the line toward a slippery slope that leads to code bloat. The step is so small that you don't notice the slope. Is it safe? Probably, because it's a trivial example. Many "doesn't it make sense to go ahead and..." cases are larger. And the larger the step, particularly if it crosses a sprint boundary, the greater the chance that you'll guess wrong, and end up with wasted work and extra, unused code. Working in a system with a lot of dead or unused code sucks.

If your team that has a problem with code bloat, I'd "set the anticipation knob at zero" for a while, until people have a feeling for what it's like to build a system in small pieces with no anticipatory design. Seeing a system evolve cleanly is something many developers have never seen. Then revisit the decision. The most productive team I worked with left the knob set to zero and kept it that way for years.

Dave W. Smith