7/31/2009

Test objects, not methods


As you may or may not know, I am part of the team pushing the boundaries of Agile & XP at Industrial Logic with Josh Kerievsky. As such, I'll be posting some of my rantings in our new Industrial Blogic album (the blog portion of our truly kick-ass "Greatist Hits" eLearning platform).
My debut there is a classic, but so grossly unknown topic. Summarize it as so: if you want to test your private methods, take out a ruler and slap yourself over the wrist. As a personal mentor of mine, J.B. Rainsberger, used to tell me: "if you really need to test that private method, then it should go somewhere else dude."
Check out the rest of the story here, and while you're in add our Industrial Blogic to your RSS reader, we'll be keeping it hot there.

7/08/2009

Checking In (but no, not source control)



So sorry, I've been sooooo lax about posting any new thoughts (very busy training for a triathlon) - trust me though I've had many, my "rants todo" list is billowing over. Soon, they will be here in all their glory for you to chew on, I promise (to both of us).

In the meantime, I thought you'd be interested to know that today we experienced two very very unique moments:
12:34:56 07/08/09 and 04:05:06 07/08/09
Won't happen again in any of our lifetimes. Wow, pretty darn neat, huh? One day past a full moon to boot.

And also, hopefully to keep you really distracted from my absense, I thought I'd treat you to what I thought to be a pretty damn funny joke my dad forwarded my way:

A Dog Story

A guy is driving around the back woods of
Montana and he sees a sign in front of a broken down shanty-style house: 'Talking Dog For Sale ' He rings the bell and the owner appears and tells him the dog is in the backyard.

The guy goes into the backyard and sees a nice looking
Labrador retriever sitting there.

'You talk?' he asks.

'Yep,' the Lab replies.

After the guy recovers from the shock of hearing a dog talk, he says 'So, what's your story?'

The Lab looks up and says, 'Well, I discovered that I could talk when I was pretty young. I wanted to help the government, so I told the CIA. In no time at all they had me jetting from country to country, sitting in rooms with spies and world leaders, because no one figured a dog would
be eavesdropping.'

'I was one of their most valuable spies for eight years running. But the jetting around really tired me out, and I knew I wasn't getting any younger so I decided to settle down. I signed up for a job at the airport to do some undercover security, wandering near suspicious characters and listening in. I uncovered some incredible dealings and was awarded a batch of medals.'

'I got married, had a mess of puppies, and now I'm just retired..'

The guy is amazed. He goes back in and asks the owner what he wants for the dog.

'Ten dollars,' the guy says.

'Ten dollars? This dog is amazing! Why on earth are you selling him so cheap?'

'Because he's a liar. He never did any of that shit.'

;-) C ya soon...
MB

5/16/2009

TDD: The Rhythm


Good TDD, well real TDD, provides the team with a heartbeat.

Everyone has a heartbeat, you know what it's like: continuous and clear, smoothly flowing, subtle yet ever so present and soothing. Its unlikely that you're explicitly listening to it, but you are without doubt subconciously aware of the supreme comfort and reassurance that heartbeat provides you each and every minute of your day. It keeps you alive!

Same is true with software development. And while Iterations, Stand-ups, and CIT no doubt provide an essential macro-heartbeat, those things aren't what give us that minute to minute assurance analogous to our human heartbeat. That's where TDD comes in - true TDD provides us that comforting development heartbeat to actually get us productively and happily through the day.

It provides the transition from story card to failing storytest (acceptance test). Then from failing storytest to the first failing microtest (unit test). Then minutes later to the first passing microtest. Then minutes later to the next failing microtest, then the next passing microtest, and our first refactoring. Then minutes later to our next quick cycle of "red/green/refactor". Then within an hour our first check-in. Then a few more "red/green/refactor" cycles and another checkin. And before you know it, after one of those cycles, boom, a passing storytest! A high-five and a final checkin, then home by 6 to see the kids.

Do you hear it? Thum-THUMP, Thum-THUMP, Thum-THUMP...RedBar-GREENBAR, RedBar-GREENBAR, RedBar-GREENBAR...
A development heartbeat.

It's this rhythm that guides you, that keeps you on track. Its what gives you the constant feedback to know, at every step of the way, that you're growing the right design, that you're satisfying the customer's needs, and that you haven't broken any windows. It's what allows you to move freely and move fast. It's this rhythm that makes you feel good. It's this rhythm that makes you feel alive and happy.

Ask anyone whose felt it. Once you've actually truly experienced this rhythm - this heartbeat - I assure you, just as with your human heartbeat, you'll find it unbearable to ever live without.


4/02/2009

PropertyFor Sale

Properties. And, Java. Lots of languages really, but let's look at Java. Every Java (and other langs too) application of any size is going to be using some properties. Typically, they'll be held in a "myspecializedvalues.properties" file, but not necessarily. For this example, let's assume you are using such a file (and can then thus use Java's built-in property management mechanism), but again, its not really the point. And this approach can be applied no matter what format you choose to store your properties.

The point of this is to show you a better way to manage - a better way to encapsulate and access - your properties so that the implementation is hidden behind an expressive interface, easy for anyone to understand and use.

The point is to show the PropertyFor class, and to tell you why its better than what you probably have in place.

So, this example has a strategy factory class that needs to make its decisions based on a property setting, this property having a true/false (boolean) value. It starts off looking like this:
public class GeneratorFactory {
public String propFileName =
"ELearningSettings.properties";

public GenerationStrategy projectGenerationStrategy() {
if (shouldIgnoreCode())
return new GenerateWithoutCode();
else
return new GenerateWithCode();
}

private boolean shouldIgnoreCode() {
Object valueObj = getProperty("CODE_IS_USELESS");
if (valueObj != null)
return Boolean.parseBoolean((String)valueObj);
return false;
}

private Object getProperty(String key) {
Properties properties = new Properties();
try {
properties.load(new FileInputStream(propFileName));
} catch (IOException e) {
throw new RuntimeException(e);
}

return properties.get(key);
}
}

You'll hopefully notice something about this factory. First, it's primary responsibility is to serve up the correct strategy to its caller. Of course though, you'll also notice that not only does this class do its primary purpose, but it also has a lot of low-level knowledge about how to obtain the information it needs to make its decision. It knows all sorts of things about icky java property mania.

Now, if this is the lone property in your system, than maybe this is okay and doing any kind of extraction here might be YAGNI (you might though, even if that is the case, be bothered by that fact that this class clearly violates the SRP, nonetheless...).

Of course though, this is not the case, and so let's assume that although this is the only class you see in this example there are in fact more properties in your system and more users of them.

So, the logical thing to do is to extract that property reading management into its own class, happy to have its sole responsibility being providing property values. You do so, and end up with this new "Settings" class:
public class ELearningSettings {
public String propFileName =
"ELearningSettings.properties";

public Object getProperty(String key) {
Properties properties = new Properties();
try {
properties.load(new FileInputStream(propFileName));
} catch (IOException e) {
throw new RuntimeException(e);
}

return properties.get(key);
}
}

public class GeneratorFactory {
public GenerationStrategy projectGenerationStrategy() {
if (shouldIgnoreCode())
return new GenerateWithoutCode();
else
return new GenerateWithCode();
}

private boolean shouldIgnoreCode() {
Object valueObj =
ELearningSettings.getProperty("CODE_IS_USELESS");
if (valueObj != null)
return Boolean.parseBoolean((String)valueObj);
return false;
}
}
You slap five with your pair and check in, this is much better! Now your factory can do it's job without having any internal worry about where the settings (properties) are really coming from or how they're implemented. Any other users of properties also get the same luxury. A big improvement, no doubt.

Many systems I've seen have figured this much out, and have this in place. A "Settings" class that hides the details of how to look up properties, all you have to give it is the key to the property you want.

But, this has limitations.

First, and as many will figure out and solve on their own, a sprawl of the property key strings hard-coded in the various users of the properties. You want to change this key? Have fun chasing all the uses down. Of course you could create a constants file for these keys, and have the callers only know the constants (which, in Java at least, provides the big benefit of being able to leverage you IDE when you want to change its name), but is that really enough?

Second, yes your factory doesn't know about "ELearningSettings" or the "java...Properties" guts, but it does still have the job of knowing the format of these property values ('Object' in this case) and how to turn that into what it really wants, a boolean.

Third, particularly if haven't created a constants file (in response to the first problem), how easy is it for future developers to go to one place and see all the possible properties/settings the system has available for them?

There may be more limitations, but that's enough for me.

So, our answer to each of these questions is where the magic happens, the MBark of this article. We evolve our generic "Settings" class into a domain-friendly "PropertyFor" class:
public class PropertyFor {
public static String propFileName =
"ELearningSettings.properties";

public static boolean shouldIgnoreCode() {
Object valueObj = getProperty("CODE_IS_USELESS");
if (valueObj != null)
return Boolean.parseBoolean((String)valueObj);
return false;
}

private static Object getProperty(String key) {
Properties properties = new Properties();
try {
properties.load(new FileInputStream(propFileName));
} catch (IOException e) {
throw new RuntimeException(e);
}

return properties.get(key);
}
}

public class GeneratorFactory {
public GenerationStrategy projectGenerationStrategy() {
if (PropertyFor.shouldIgnoreCode())
return new GenerateWithoutCode();
else
return new GenerateWithCode();
}
}
What did we do here? Well, we've taken all the knowledge highlighted above as our limitations and removed it from our factory (really, from all of the users of settings), and put it into our "Settings" class - which, as a result, now becomes a more useful, expressive PropertyFor utility.

So, you'll see our factory now has to worry just about choosing a strategy, and no longer has any overhead related to obtaining the values it needs to make its decision. More specifically, it doesn't know where the settings come from, doesn't know the details of how to access them or the keys that identify them, and it doesn't know what raw format they come in. The factory knows it needs the boolean value of whether or not to "ignore code", and it gets that in one clear, simple line of code.

Further, you've got the beauty of expressive methods on singular class to be very domain-centric in assisting other programmers to access the available setttings/properties for your system - these methods, not only being clearly and expressively named, but also being typed appropriately for ultimate ease to the consumer. And of course, when you need to change the name of the setting and/or the name the callers know it by, no problemo.

So, that's really the main meat.

For good measure though, we take a moment to improve the design of our PropertyFor class. First, this isn't the only boolean setting we have (use your imagination) so we should have a nice clear reusable method to handle our boolean typed settings:
public class PropertyFor {
public static String propFileName =
"ELearningSettings.properties";

public static boolean shouldIgnoreCode() {
return boolanValueFor("CODE_IS_USELESS");
}

private static boolean boolanValueFor(String key){
Object valueObj = valueFor(key);
if (valueObj != null)
return Boolean.parseBoolean((String)valueObj);
return false;
}

private static Object valueFor(String key) {
Properties properties = new Properties();
try {
properties.load(new FileInputStream(propFileName));
} catch (IOException e) {
throw new RuntimeException(e);
}

return properties.get(key);
}
}


And then, it really is pretty inefficient of us to read the properties file over and over, so let's take care of doing that just once and being done with it:
public class PropertyFor {
public static String propFileName =
"ELearningSettings.properties";

private static Properties properties;
static {
loadProperties();
}

private static void loadProperties() {
properties = new Properties();
try {
properties.load(new FileInputStream(propFileName));
} catch (IOException e) {
throw new RuntimeException(e);
}
}

public static boolean shouldIgnoreCode() {
return boolanValueFor("CODE_IS_USELESS");
}

private static boolean boolanValueFor(String key){
Object valueObj = properties.get(key);
if (valueObj != null)
return Boolean.parseBoolean((String)valueObj);
return false;
}
}
So there you have it: PropertyFor.

And, of course, this isn't a post about TDD, but here is the test that was in place and passing before and after any of these refactorings went down:
public class GenerationStrategyFactoryTest {
@Test
public void needingACodelessStrategy() {
propertiesFileIs("CodelessGenerationStrategy");
assertTrue(strategy() instanceof GenerateWithoutCode);
}

@Test
public void needingACodeStrategy() {
propertiesFileIs("IncludeCodeGenerationStrategy");
assertTrue(strategy() instanceof GenerateWithCode);
}

private void propertiesFileIs(String fileNameBase) {
String filePath = "testdata/"
+ fileNameBase + ".properties";
PropertyFor.propFileName = filePath;
}

private GenerationStrategy strategy() {
return new GeneratorFactory().
projectGenerationStrategy();
}
}
As an exercise, go ahead and write the test you think I have for the PropertyFor class, because of course you know I do!


ps// I'm really not liking this code highlighter library so far. Any other Bloggers have good suggestions for a good library?!?

3/28/2009

Doing The Right Thing And Getting It Done

Been following my man Corey as he moves along on his Journeyman Tour (which I posted about on InfoQ at its onset), in fact had dinner with him tonight!

Here's a talk he did recently on "Practice", which I'm totally in agreement with. Check it.


Practice - Corey Haines from 8th Light on Vimeo.

Keep on keepin' on, Corey!

3/27/2009

Killing "Quality"


So, a guy walks into a bar...

No, just kidding. But seriously though...

You walk into a bar and order a "low quality" beer (tough economy these days). What does this mean to you? That it'll come out with a bug swimming in it? That it will be served heated up? That it will be skunked? Glass only half full?

No, of course not. You'd be appalled, outraged. Have every right to ask for your money back. This place has acted in bad faith, they've acted unacceptably. You leave angered and vow to never return.

Your wife wants you to drop $600 on a new Louis Vuitton bag (you gotta buy cheap beer and she' still asking for Louis?!?), because it's a "top quality" product. Does she describe it this way because she knows it has less likelihood of falling apart the minute she gets it, or its colors smearing, or it having holes in the bottom? Again, no. These things are assumed to be absent. In the rare case you do happen to find anything like this, you are sure to invoke "return to sender, no questions asked".

I could continue on this way throughout various types of products, but I suppose you get the point.

Well, this ain't the case with our industry (Software Development). So I ask ye: WTF, man?

We use the word "quality" as an indicator of both "value" and/or "defect" presence, interchangeably.

When someone says "high quality" they could very well be talking about the absence of defects or they could be talking about the presence of value. And by software standards, neither would be an inappropriate use of the word.

Not so in the bar, not with your beer. Why then for us? Again I ask, WTF?

I know, I know. Some of you are sitting there saying (correctly), "hey, wait, agile pays attention to customer feedback to iterate towards a higher quality solution. We're talking about 'value presence' there." Or maybe your saying, "Our company's website says 'highest quality product in the industry!'. That's talking about 'value presence' too! That's what we mean when we say 'quality'."

Well, maybe so (and good for you, seriously). But I bet many of you still call your testers "the QA folk". "QA", as in Quality Assurance, as in "Those who ensure quality". But really, is their (primary) function that of ensuring 'value presence', or of ensuring 'defect absence'? Look, don't get me wrong, on a healthy agile team these wicked cool cats ARE involved in 'ensuring high value', but at the end of the day that isn't why you're calling them "QA'ers".

I've seen my share of "quality review" meetings, or fancy charts of "quality metrics", or annual budgets that talk of "quality goals" ... where in each of these cases, "quality" is talking about DEFECTS.

When was the last time someone described the benefits of TDD without mentioning, excitedly, "increased quality"? (And, yes indeed, I am certainly just as guilty as the next guy.)

So, why do I care? Why the rant?

Because, it's an indication of the generally absurdly high level of tolerance our industry has for defects.

That we describe defect density with the same word that we use to describe product "value" (to our customer/consumer) is gross.

Heck, I'd go as far as to say its a part of the reason that we have such a generally high tolerance in the first place. It's confusing and it is misleading. It's too easy to masquerade our defect problems as a "quality improvement initiative" or some other politically wimpy label.

When our customers get a bunch of "bugs in their beer" why aren't they appalled and outraged? Why aren't we? Why don't they storm out and vow to never come back? Why is it so damn okay to have defective software? For the third time, WTF?

Don't get me wrong, I'm not saying we should have an absolute "zero defect, period" attitude, that's simply unrealistic considering what we do. But we should have a low enough tolerance for defects that it makes no sense for us to use the word "quality" when talking about them.

"Quality" should be used as a measure of functional/aesthetic utility to our consumer, and not as a measure of defects. Really, it should just be assumed that defects are generally absent. This should just be implied in what it means to be a Professional.

So:

I hereby propose we as software professionals and businessmen stop using the word "quality" to mean a "measure of defects".

Well then, what word will we use? I polled Twitterverse with this question and received lots of great responses, but the group's choice as winner, courtesy of one Brian "Big Ball Of Mud" Foote, is this:
Shittiness.

Software with minimal defects has a "low degree of shittiness"; lots of defects means it has a "high degree of shittiness".

Of all the tweep responses though, overall my very favorite was from Lisa Crispin who said, "I have never liked measuring defects so it's hard to think about what to call it."

Nice, now that actually says it all. Something tells me that Lisa's company does not simply think of their testers as "the QA folk". There is hope!

3/22/2009

TDD: The Synergy


TDD. What does this stand for?

Test Driven Development.

Said another way: Development, driven by tests.

Notice, the acronym doesn't stand for test driven design. Not test driven analysis. Not test driven coding. Nope, not even test driven testing. It is, again, test driven development.

TDD is not a "task". It's not a thing we do in addition to doing design, or in addition to writing production code, or in addition to "writing" stories. Rather, TDD it is the way we design, the way we write code, the way we define a story. It is the way we do development.

When done well, TDD exists at root of nearly everything we do in our agile team - it is the team's minute-to-minute comforting heartbeat.

TDD means that "writing a story" equates to specifying in an automated acceptance/story test (most often using FitNesse, Selenium, WaTiR, or something similar) "what it will look like" for a story to be working once we've implemented it. How the new application feature monickered on the story card must behave for it to be DONE.

TDD means that "designing" equates to specifying in an automated unit/micro test (most often using a member of the xUnit family of tools) "what it will look like" for any particular object to work once we've implemented it. In other words, what the expected behavior of that object is.

TDD means that "coding" equates to letting that unit test tell us when we've written working production code. Possibly more importantly, it means that "coding" equates to letting those passing unit tests ensure that our object continues to work (satisfy it's expected behavior) while we mercilessly refactor that object to keep it super clean and expressive.

And, in case you didn't notice in the above assertions, it means that our development is driven by tests. This means that the test is written first. The existing [failing] test is what drives us to conjure up production code. The test is the only reason for us to write a line of code. It's the only way we know what code to write - the test is our specification. Yes, we can write production code first then try to write a unit test to verify it's implementation, but, in addition to the mechanics of that likely being extremely difficult and counter-productive, that's simply not TDD.

Make no mistake about it. True TDD, at the acceptance (Story/Service) test level, is an act of analysis. And true TDD, at the micro (unit/object) test level, is an act of design. In a single statement: True TDD is much less an act of verification (as the "test" part of the name might accidentally and incorrectly imply) as it is an act of specification.

In summary, TDD provides the fundamental synergy between and foundation for all of our development "tasks" that enables us to truly build the right software and to build the software right. It ensures quality2 - which, in the end, is the only true way for us to go fast and go fun.



** Upon further review, authors are changing the catchy phrase "ensures quality2" to the more appropriate phrase of "ensures high quality and low shittiness"

3/10/2009

Rubber Duck Debugging




From an ethernal.org discussion:

"We called it the Rubber Duck method of debugging. It goes like this:

1) Beg, borrow, steal, buy, fabricate or otherwise obtain a rubber duck (bathtub variety)
2) Place rubber duck on desk and inform it you are just going to go over some code with it, if that's all right.
3) Explain to the duck what you code is supposed to do, and then go into detail and explain things line by line
4) At some point you will tell the duck what you are doing next and then realize that that is not in fact what you are actually doing. The duck will sit there serenely, happy in the knowledge that it has helped you on your way.

Works every time. Actually, if you don't have a rubber duck you could at a pinch ask a fellow programmer or engineer to sit in."


I must say, I do quite like this. I must also say, THIS IS WHY WE PAIR!

Having (hell, getting) to vet your thoughts out-loud, in real-time, with another person is a fundamental benefit of pair programming, one of the primary reasons overall productivity is increased, not decreased.

Forget asking "at a pinch", have him there all along!

Thanks for pointing me to this Buffer, fun stuff!!!

3/02/2009

Nutshells: Why TDD?

So, ya need that techie-friendly quick-pick-list to explain to someone why your project simply cannot live another second without TDD? I know I did, so I created one. And I'd like to share it with you faithful readers.

Confidence & ProductivityToday
  • Immediate feedback, ie. "cookies": Green bars that give me full confidence in what I’m coding, or in other words, meeting requirements with decreased bugs

  • A more efficient design:
    • Clear “expectations” (tests) drive my mind quickly and smoothly to solutions (algorithms)
    • Good public interfaces – my tests make me “eat my own dog food”
    • Simplicity – I’ve coded only what was needed to pass the tests
  • A more effective design: in order to write software that is effectively tested in this manner, I’m naturally encouraged to ultimately write more cohesive and less coupled code
  • Test “protection”: “my tests” give me freedom to refactor mercilessly to create a more expressive, readable code-base while I’m coding
  • And then even more Test “protection”: “all the tests” allow the build to silently ensure that today’s collective changes across the group haven’t broken any windows

Confidence & Productivity … Tomorrow
  • Fact: addressing yesterday's bugs exponentially decreases today's productivity...unless:
    • yesterday 's TDD decreases (if not nearly altogether removes) yesterday's bugs

  • Fact: most bugs occur upon changing an existing code-base...unless:
    • Today’s [automated] tests become your safety net tomorrow
    • Growing test suite allows build to be the perpetual “silent police”

  • Fact: easy to understand my design; hard to understand your design...unless:
    • Today’s [expectation-based] tests become your documentation tomorrow
    • My expressive code is easy for you to understand tomorrow

  • Fact: “code rot” (poorly factored code) slows development over time...but:
    • My tests force me to keep my design well-factored – forever!

  • Fact: “paper documentation” gets outdated (and lies!) over time...in contrast to:
    • Automated Storytests: up-to-date, runnable “what it does” documentation (analysis)
    • Automated Microtests: up-to-date, runnable “how it does it” documentation (design)

Of course, I'm not perfect, and feedback is king. So, please, pretty please with sugar on top, let me know how you think this list can be improved!

2/13/2009

Wringing Necks


Re: Title. Sorry, its Friday the 13th, couldn't resist!

Anyhoo...I was checking out this InfoQ post which asks the question of whether you need a single person as your "Product Owner" or it can be many. I have my opinions about the answer to that particular question, but I'll save that for another post. It's the undercurrent of that question I want to discuss now.

"One neck to wring". "One throat to choke." I've heard this and similar statements for years in reference to Product Owners (in Scrum terms that is; in XP, we may say Customer). In other words, there are people who make the statement that part of the Product Owner's role is to be the "one throat to choke", the "one neck to wring".

My take on this is similar to my feeling on the "Chickens & Pigs" thing: me don't like it, and here's a quick run-through of why.

This euphemism, at its heart, is a statement of accountability. It basically implies that the Product Owner is accountable for the outcome of your agile project, for its successes and/or for its failures. Beh, hogwash.

Let's backtrack a tad (just can't help myself ;-). I'm a believer that there exists at least these two primary degrees of agile teams:
  • Agile Team v1.0: practices have been installed and people are following their agile methods generally as the book tells them. They are following the mechanics, that is, but that's all. What's missing? Well, a real team. Agile Team 1.0 may not be a bad thing, it's likely to be a much better thing than to have no agile at all, but it's not the hyper-productive thing your executives were clamoring for.
  • Agile Team v2.0: as with v1.0, the team is following the practices, but this team is a real team. In other words, the team is truly "self-organizing" and empowered. This team understands and manages the interpersonal aspects of good teamwork. This team truly understands that at root of success are people, and the interactions between them. This is the team that execs bought into [noun] "Agile" for; this team kicks ass.
Said another way, in Lencioni terms, the members of Agile Team 2.0 trust one another, engage in unfiltered conflict around ideas, commit to decisions and plans of actions, hold one another accountable for acting on those decisions, and focus on the achievement of collective results. Agile Team 1.0, on the other hand, does not do all of this.

Highlight: "...hold one another accountable...". There ya have it, Agile Team 2.0 is a team that shares its 'Accountability'. Each member is accountable; the developers, the testers, the CM folks, etc..., and finally, yes, the Product Owner (Customer) too. No "one neck", no "one throat", everyone.

Bottom line, if any one person holds the accountability for success/failure on your agile project, particularly if that one person is your Product Owner, you've got more to learn about how to be [adjective] agile, about how to be a team.

The good news is that you're not the best you can be, you've got room for some big improvement, how lucky!

2/12/2009

{"X} + {"Y"} = {"X", "Y"}


Adding 2 Java arrays in 4 lines.

First, and foremost, do your damndest to avoid the use of primitives. If you're in the 21st century anyway, we have higher level languages and those languages have objects and, hot damn, let you make objects - so use them!!!

Be assured you'll hear more from me on that front for a long time to come. Anyhoo though...

This quick post is about when you, for one legit reason or another, do have to work with primitive Java arrays. As in "String[]" array, not "ArrayList<String>".

Today, Gil and I had to and were quite miffed to find there was no easy built in way to combine to existing arrays. Once the disgust was gone enough to type again, we coded a little utility to do it.

So, here's what we ended up with:

public static String[] arrayAdd(String[] one, String[] two) {
String[] newArray = new String[one.length + two.length];
System.arraycopy(one, 0, newArray, 0, one.length);
System.arraycopy(two, 0, newArray, one.length, two.length);
return newArray;
}
Do note please that this creates a third array which is thus returned (as opposed to actually changing the state of either one of the input arrays).

If you've got better suggestions (libraries, whatever), shout em out. Otherwise, enjoy.

And, yes, of course, we do have a test for that!

ps// can't help it.  To reassert my initial point, "resist your primitive obsession", using a List (object), of course, you get:
public static List<String> listAdd(List<String> one, List<String> two) {
List<String> newList = new ArrayList<String>();
newList.addAll(one);
newList.addAll(two);
return newList;
}

..and then of course if you don't want a new collection instance:

one.addAll(two);

2/03/2009

Mi Code-ah, Su Code-ah


In one sentence, what does 'Collective Code Ownership' (CoCO) mean?

In the words of Kent Beck, it means "Anyone can change anything anytime".



Said another way:  There ain't no such thing as 'My code, your code'.  Them there is bad words, mi amigo.

And then, in many more sentences...

How many times have you been routed a defect that came out of your team but you had no idea how to address it because you "didn't code that part"? How many times have you been unable to take on a story because "Jerry's the only one who knows the business logic"? How many times have you been unable to proceed until you got approval from the person who "knows that code"? How many times have you had to leave a story on the shelf because the person who "owns that code" got wolfed for a few days (or "hit by a bus")? I could ask these questions forever but I'll stop there, I expect you get the point.

Thus, as one of the main practices that stems from the value of Collaboration, Collective Code Ownership aims to break those recurring enemies of productivity. It says that, certainly within at least a team, everyone owns all the code. Furthermore, everyone is free to...scratch that, everyone is responsible to be equipped to effectively make updates to absolutely whatever code their story takes them to -- without feeling like an intruder and without having to get "permission" or any non-casual advice from your so-called "expert" or "owner". From a more measurable POV, CoCO states that everyone on the team (developer-wise) must be able to describe the design of anything the team is working on in no more than 5 minutes.

So, why possibly might this not always happen? Well, I see at least a few reasons.
  • First, it requires a very high level of collaboration and trust within a team, something that, unfortunately, isn't necessarily present "We've gone Agile! Day 1".
  • Second, it might not absolutely require it, but a test-covered, well-factored, and expressive code base goes a very, very, very, very, very long way to making this work. Ok, I lied, it is required. And again, this is something that for many new teams is simply not the situation.
  • Third, in many cases, particularly on bigger enterprise-y projects, it simply takes a good amount of work and an investment in time (which, of course, is money) to make this happen. Alas, to much dismay, its an investment that often ends up taking a back seat to "hittin' that next deadline".
And lastly, it takes courage. It takes being comfortable with stepping out of your "comfort zones" (pun intended) every now and again. It requires shifting your self-image from "I'm good at working on this code" to "I'm good at working on code".

Heck, isn't that why you became a programmer in the first place? You didn't start your days banging on the keyboard dreaming of being "the dude who knows the billing system inside & out", or "the keeper of the logging framework", or "the Hibernate guy" did ya? You loved code, programming, creating things, bringing new stuff to life, a real Doc Frankencoder. Tap back into that, set the inner geek free, you'll be happier for it.

And, you're in luck, the benefits do not stop there.

At a team level, having a collective code ownership implies more freedom to have people pick up the most important stories or tasks, independent of what part of the app they may affect. It allows you to focus more people on the next story, to have the team bum-rush it, get it started then completed quickly before moving onto the next most important story, which in the end is a better way to run your iteration than to "multi-thread" many concurrent stories.

Does this mean that your team will religiously have everyone working on everything, everyday?  Course not, even if that did make sense, it ain't physically possible (in this dimension).  But it does mean that you should switch up pairs periodically (preferably at least daily), and share a story's tasks amongst your pairs. Have pairs face each other and be in earshot, rather than nestled off in their own cubbies and corners.  Have team design pow-wows around the whiteboard and code reviews around the projector every couple days. Use your wall-space to document decisions and debate working designs.  Collectively own the problems, collectively own the decisions, collectively own the code.

And at an organizational level, Collective Code Ownership allows your teams to grow in a way that keeps up with the way your product matures.  Many applications will start their life having intense development needs in each of its various components, and logically teams will form around these components.  This may work initially (or it may not), but it comes with a natural tendency for silos of knowledge to form around the components, which will become problematic and counter-productive as the product matures and the user's needs shift away from "component-based enhancements" and more towards "application workflows" that span multiple components.

So, yes that's right, I'm saying that Collective Code Ownership in fact goes beyond "your team"; it applies as well to "your organization".   Do the same rules apply as within the team?  "Everyone codes everything everyday", "pair with everyone", "describe the design in 5 minutes", etc?  No, it doesn't necessarily mean that.  But it does mean that you should initiate mechanisms for people to periodically get a glimpse into what other teams are working on, both functionally and technically.  It does mean that you might need to let your teams re-assemble now and again to spread knowledge and prevent yicky silos.

And finally, most importantly and most simply, whether "your team" or not, Collective Code Ownership, more than anything, is a state-of-mind:  if you need to change some code, then damn it,  its yours to change - and that's all good!

* Check out also what we IXP'ers say officially about "Collective Ownership".

1/26/2009

Burning-Down the house


A (the?) primary essence of agile is to focus on delivering value-adding functionality as often as possible. Value-adding, that is, from the point of view of your consumer.

[Quick aside: we most often think of this in terms of value-adding 'application software', but certainly not by rule - it is whatever it is that is of value to your consumer. If you don't have a consumer, or if you aren't bringing value, then why are you spending time on it? Anyway...]

The implication of this is that many tasks we perform, while in most instances are in fact (hopefully) necessary, do not in and of themselves provide any real 'customer' value. In software terms, for example, this means that while "analysis" or "coding" or "testing" activities might in fact be necessary, they are not what our consumer/customer seeks…it is "a working feature" only that truly provides the value.

Let's bring into the discussion that holy agile grail we call a "story" (a symbol/moniker for a value-adding feature) - it is assumed that all the tasks that have to occur to deliver a story will occur, but alas, we simply should not be giving or getting any cookies for completing these tasks. We get cookies only for delivering [running, tested] features; we get cookies for delivering value.

More to the point of where I'm going with this, its not really to any benefit then to explicitly track these tasks (ie, track, meaning in your reports, "backlog" if that's a tool of yours, or things similar). Why? Well, primarily, simply because it is the story (feature) we strive to deliver, not necessarily analysis or code, etc.

(Taking a bit of a tangent here, but its an important one...) "Deliver value as often as possible". The further implication here is that we also strive to break the feature up into smaller and smaller pieces (stories); the smaller, the quicker it can be delivered, eh? And, further, the smaller the more likely to have an accurate estimate; the easier to design in an evolutionary way; the easier to test; etc. But in the end, with respect to our "stories", no matter how small we split, we do not split by tasks - each split in and of itself must still provide some sort of demonstrable value. Anyhoo...

"So Mike," you say, "where in the world are you going with all this?!?!". Great question, here it is: (MBark of this post) Do away with your "burndown charts".


The sprint "burndown" [pictured left], at least as prescribed by Scrum, is tracking tasks. Being we like not to focus on tasks, and being we only get cookies for completed stories, doesn't a burndown focus us on the wrong thing? Yes, it does. Bad burndown, bad. In addition to focusing us on the wrong things, it burdens us to worry about too many things; to, in many ways, encourage us to micro-manage (which, of course, is not good for anybody and very un-agile). If you need more, how about the fact that it can lead quite readily to false-negatives with respect to how "done" you really are: "great, Bob, you've got task x, y, and z's hours all used up, sweet!"...but, uh, what the heck does that really mean with respect to the status of obtaining your real goal (delivering the feature)?



Thus, a "burnup" [pictured right]. A burnup tracks only features (whatever that might mean in your context); the features represented by stories, each assigned a point value to indicate size. When a story is complete (a feature is "done"), the burn goes "up" by that feature's points. No hours, no tasks, no minutiae about various random "inputs" - rather, just a simple representation of what we really care about - features being output. Easy-peasy, and way more in line with our goals. And, of course, as far as contributing as a tool to help us determine our velocity: if we really need to measure anything, what we really want to be measuring is our rate of delivering working software, not our rate of "doing analysis", right?

Be not mistaken by my message, it's not to say you and your team won't have daily knowledge of what particular tasks might be going on, I sure as hooha hope you do! It's just that we don't go so far as to officially track or measure them. That's what your daily stand-up is for. And, of course, common sense is required, if you really want them to be visible, fantastic (I mean it) - go ahead and hang up some task stickies on your Storyboard or some other "information radiator" hanging in your team room.

But, alas, my spidey-sense says: unless you're hoping to burn down your project, steer clear of the Burndown chart.

1/11/2009

Riddle Me This, Mr Pair Programmer


"So, my programmers were pairing; one was on the middle-tier stuff, the other on the UI layer. Things didn't seem too efficient to us. What's up?"
Two people working on different "pieces" of the same story, even if simultaneously, is not "pair programming" - this is plain old fashioned delegation. In fact, this often decreases overall productivity, due to the fact (one of many) that putting the pieces together often exposes mismatching interfaces requiring varying degrees of rework.

"Pair programming" means two people working together, side by side, on the same exact piece of code - two people thinking and talking together, one person [happens to be] typing. Furthermore, 'one person typing, one person watching' is also not "pair programming"; the key to pairing is two people thinking as one...two people collaborating.

"How to best go about selection of pairs?
Pairs should typically not be assigned, they should be formed naturally on their own. [But, see the next question for more info]

"I suspect that some pairs, for example two junior programmers, might be less effective and thus decrease productivity and code quality. Is this true?"
Yes, technically there is some truth to this... at least at the beginning. Part of the point of pairing is to help share skills and knowledge, so it may help to match up more skilled with less skilled.

BUT, much more true when you start pairing as a team, not so much once you've been at it for a little while. Once everyone is of relatively equal understanding (of the practices at least) everyone should pair with everyone. The only requirement is that the two people get along from a personal POV (and if they don't, maybe they shouldn't be on the same team anyway?). Within reason, the more "movement" the better. @see Promiscuous Pairing.

Also, something else to chew on. Having "preset/preference" pairs actually works a bit against the desired outcome - the essence of PP is having "two heads" working on one problem, in sort of a checks & balances way; the longer 2 people work together, the more they become "one head", which in large part works against the goal ("two heads collaborating").

"Do we need a certain minimum level of skill across the team before taking on pair programming?"
Absolutely not. Getting to a shared higher "level of skill across the team" is an outcome of PP (not a prereq).

"Is there a way to verify the quality of a pair that is not that experienced?"
The team should simply pay attention and use common sense.

"Is PP appropriate for some tasks and not others? Aren't small complexity activities not worth pairing on, since it just delays them?"
No.

First, on a slight tangent, part of our goal as craftsman in general is to make all tasks "small complexity", ie. simple - small stories and evolutionary design exist in large part to virtually eliminate "large complexity" altogether. When everything feels like a "toy example", then we've succeeded.

Anyway, the "stupid typos"/"silly decisions"/"shortcuts"/etc are actually more likely to occur for the "simple tasks" becuase the programmer often sees it as just that: "oh, this is just a simple little thing, I don't really need to TDD/[fill in the blank], what could go wrong"...and wallah, we've got a broken window.

Now, all that said, yes, if the task is truly a few minute trivial thing, then it may not help to PP. As with all things, common sense is required.

The truth is that the time where one in fact might be better off working alone is when they have a real doozy of a problem that they need to concentrate very hard on to get their head around. If you need some quiet dorm room time, go ahead and split up for a stint. Prototype, spike, get your head about you, then regroup and get to it. Rule is though: "No non-throwaway code during solo time".

"Should teams adjust their expected velocity to account for the effect of pair programming, especially when first adopting?"
My experience is that velocity rarely decreases enough to try to predict it - assuming they pair effectively (which is not hard), the benefits are often gained immediately.

"Do we need to pair from the onset of a story?"
Yes.

"In other words, can a story be begun by one person, then a pair picked up halfway through?"
Not advised.

Pairing actually tends to be a bit counterproductive if "picked up halfway through", mostly because the "pair" comes on and is quite likely to become, at best, a bystander observing what the other has done / is doing, or, at worst, just "a pain who won't stop poking holes in my design".

Again, true pair programming means the two are largely thinking as one, just so happens only one person is typing.

If pairing is attempted "half way in", the result is often "one person thinking, another person simply watching" - which, consequently, is more of a waste of time than a benefit.

E-A-G-L-E-S, EAGLES!!!

Sorry, I just couldn't help it! GO BIRDS!!!

1/09/2009

Where'd Jeff Probst go? (aka, Kicking someone off the island)


Yesterday I spent the better part of my morning reading through the 130 or so messages in the Scrum Dev Yahoo group's "Rotten Apple In Scrum Team" discussion, then I posted this "newsy" summary of the discussion on InfoQ.

In a nutshell, Marko told the group of a guy on his team he sees as a drastic "under-performer", or as he put it originally a "rotten apple", and asked for advice as to what to do with him. Read the InfoQ post to get a deeper sense for how people responded, but the gist of most of the advice was for Marko to take an open-minded and objective stab at finding out (and/or helping the team find out) what's really driving this person's performance, or, rather, lack thereof. And then to help him out.

"Try 'Beginners Mind'"..."take queue from Linda Rising"..."pair up with the guy"..."be nice, be helpful, be supportive"...and so on and so on. Hear this clearly (before I get to my real point of this post): I generally agree wholeheartedly with all the advice presented.

Now though, all that Dr. Jeckyll buildup for the Mr. Hyde thought: 130+ replies and not one mention of "kicking someone off the island"?

[...and the crowd gasps in horror...]

I've seen, and I'm sure you have too, a team who had an individual who truly did bring the team down. Typically not because they couldn't program quite as fast, or weren't quite as smart, or weren't quite as good in front of customers, or anything skill/experience/productivity-related like that. Rather, simply because they had a negative attitude, because they didn't play nicely or just plain didn't care.

[*Note: For what's worth, I do not think this applies to Marko's guy, but the discussion got me thinking anyway.]

One seriously under appreciated technique that I stress should be considered for these true "rotten apples" is to get them off your team, kick 'em off the damn island. No one says you have to fire them, just get them out of the way somehow.

Forget tools, intelligence, certifications, experience for a moment. The degree with which having a good team (in the "synergy" sense that is) contributes to good results (and, hell, a good time) is amazing; having a great team, well that's just indescribably astounding, magical even. Conversely, the degree with which having a bad team atmosphere can lead to serious bed-shatting, well, that's also quite amazing as well.

So if you've got someone who after the Prime Directive and the Beginner's Mind and the Pairing has still got that sour-puss face and, more importantly, is still killing your team's ju-ju, then by all means call the spade a spade, cut your losses, and remove them. Be as graceful as you like, but please, as Bo used to say, just do it.

Again I stress, I'm about as "glass half full" as they come - I'm not trying to encourage a general exclusive, head-chopping, "only the best" attitude. 95 times out of 100 your man intends the best and just needs a little love, and by all means you outta be doing your damnedest to facilitate that happening. My point is that for those other 5, stop being so P.C. and get the bad apple out of your basket. Your team's ju-ju will thank you for it.

** Update: Thanks to Esther Derby for shouting out about her related and more concretely useful post from some time ago echoing the same sentiment.
 
/* */