25 May 2009

If Software's Like Farming, How Do I Certify Organic?

The abundance of software metaphors is amusing.

Before writing code, we used the archaic but apropos writing instructions. That is because writing instructions is literally what we did, uh... and still do.

If I used Twitter, and you followed me, you'd find that on most days,
Bob is slinging instructions.
Metaphors abound for the stuff that happens between digital nothingness and an app one can demo. A sampling from blog posts Why Software Development isn't Like Construction and Tending Your Software Garden borrow metaphors from several industries attributable to various software luminaries (see table).

Metaphor
Industry
Remark / Attribution
Building an app
Construction
Software is soft, buildings aren’t (McConnell)
Creating an app
Theology
It's a science (Gries, 1981); It's an art (Knuth, 1998).
Growing an app
Farming
Hunt and Thomas, and others
Accreting an app
Oyster Farming
e.g., system accretion (McConnell); oysters make pearls
Driving an app
Transportation
"like driving a car"" (Plauger and Beck)
Producing an app
Entertainment
"like filming Snow White and the Seven Dwarfs" (Heckel)

Teams freshly introduced to agility might feel they're divining an app; not unlike a dowser might try conjuring up Sahara groundwater from the nearly imperceptible twitches of his divining rod.

I am partial to the Farming metaphor. Are you? I have started using grow instead of build in professional conversations - whenever I can remember.

In keeping with the post Simple Design or Swiss-Army Knifing, I pledge to strive to minimize my natural tendency to over-fertilize (i.e., I will deny the impulse to shovel on piles of steaming manure - one method, one purpose).

If software is like farming, how much manure should we use?

22 May 2009

Simple Design or Swiss-Army Knifing?

Naresh Jain's Managed Chaos has a short post reminding us to Embrace Simple Design.

Naresh uses the phrase:
“Smartest Possible Thing That Could Possibly Work”.
Stick that bromide in your quiver. I like that sentence.

Version One's
marketing material refers to simple design, quoting poet Wallace Stevens
"the art of what suffices."
- Wallace Stevens
in reference to growing application functionality that is
for today's story, and today’s story only
Sadly that advice is counter to our natural inclinations. We love to flex our muscles to unwittingly complicate things.

I sometimes feel victimized by Swiss-Army Knifing on the development team. Forget about gold plating being bereft of value to our product owners, I am referring to so-called re-usable components that well-meaning developers build. It's an affliction that inexplicably infects the C# practitioners more so than purveyors of Java.

Many times re-usable components are a detriment to the development team who feel obliged to use them. These re-usable Rube Goldberg contraptions present technical debt we must shoehorn into our code because...well ...because, um, they took so long to build?

Many of us have the unfortunate proclivity to grow do-all components; ostensibly for others to re-use. Unfortunately these knives do more than cut. Much more. So much more, they don't even cut very well. Our Swiss Army knives end up being clunky and difficult for others to understand. Plus, they sag our pants. Turn Jam into Jelly.

Is the Swiss Army knife approach little more than the flexing of coding muscles?

In XP, the acronym is YAGNI, for

"You Aren't Gonna Need It"

Let's resolve to keep it simple.

I plan to heed Naresh's advice to focus on, the “Smartest Possible Thing That Could Possibly Work”.

Thanks for the reminder.

20 May 2009

Team Manifesto - Craftsmanship, Behavior & Minutiae

When Dilbert cartoonist Scott Adams puts a Team Manifesto Generator on his website, the Team Manifesto concept will have jumped the shark; just like the American situation comedy Happy Days did when Fonzarelli donned water skis to jump over a shark ("Fonzie" left).

Until then, I am on board with having a Team Manifesto.

Articulating the team's definition of craftsmanship, establishing the team's technical standards, and declaring the team's inter-personal behavioral policies provides a path and a prenuptial agreement of sorts.

How do we keep the Team Manifesto relevant? How do we keep it from jumping the shark?

Three suggestions to prolong the viability of your Team Manifesto:
  • It should be visible - prominently displayed rather than buried in a Wiki;
  • It should be regularly revisited at retrospectives; and
  • It is an expression of the team's constitution: by the people, for the people.
Three suggestions for seeding and feeding your Team Manifesto:
  1. Craftsmanship Contract - How do we define quality?
  2. Behavioral Contract - What's acceptable behavior?
  3. Organizational Minutiae - What time is our stand-up meeting?
Craftsmanship Contract - How do we define quality?

Establishing a mutual definition of quality is challenging because the question
What does quality means to you?
is open-ended.

A craftsmanship contract taps into the team’s professional pride. Successful craftsmanship contracts will presumably be self-enforcing. That is, since it's mutual, team members are likely to strive to meet its standards and to encourage teammates to do the same.

A team member's definition of craftsmanship might be quite different from yours. Try to coax your teammate's professional narrative from him so that you might better understand how he's formed his story about quality and craftsmanship.

One team member might place high value on performance; that is, for her, quality is measured by how fast a method executes. Other team members might take an initial pass on performance in favor of delivering working software frequently. Cultivate and harvest the overlap in your narratives.

Reaching an understanding of what quality and craftsmanship means - in a collective sense - gives the team a common rudder to steer to toward the elusive qualities of quality.

Finally, distill and translate the qualities of craftsmanship into testable assertions like methods will have one purpose only.

Behavioral Contract - What's acceptable behavior?

Establishing a list of behavioral do's and don'ts enables the team to head off many conflicts at the pass.

The list might include a policy for paired programming, a policy for acceptable interruptions, the definition of personal spaces, a policy for re-factoring someone’s code, a policy for attending to broken builds, etc.

Goofus & Gallant
, contrasting characters in a preachy cartoon strip that appeared in the children's magazine Highlights, were ostensibly intended to teach children social skills. The cartoonist's pattern was to illustrate how differently two boys, Goofus and Gallant, responded to the same situation.

As a child, I summarily dismissed the lessons and modeled the bad guy, Goofus. As luck would have it, Goofus & Gallant are much more apropos to the contemporary workplace; particularly a workplace inhabited by boorish colleagues who behave like children and who have managed to coast into adulthood without having cultivated minimal sensitivities to social queues.

Goofus bosses his friends. Gallant shares his orange. Figure out good and bad behavior on your team. Agree on the behavior the team should model.

Organizational Minutiae - What time is our stand-up meeting?

This one's the easiest. Make a schedule. Stick to it.

18 May 2009

Beware The Seductive Narrative

I know little about who reads this blog, but I am smitten with ClustrMaps's geographic mashup widget.

A Bobtuse Bobservations ClustrMap charts visitors from Argentina to New Zealand with red dots scaled to volume.

I seem to have developed a fatal attraction to the statistics logged and lipsticked by FeedBurner.

FeedBurner's allure is its charting dashboard; it sashays subscriber numbers across a plot that sings a siren-song of your "reach" over time. It lures you with its come-hither page click tallies for each blog post.

If we could tap into the Delphic oracle for nascent blog-writers, we might have found the prescient heuristic Know Thy Audience.

But what do these data tell us?

Examining these data, it is easy, actually, rather seductive, to construct self-serving narratives. For example,
The Narrative Fallacy, brought to our attention by Nassim Nicholas Taleb in The Black Swan: The Impact of the Highly Improbable, refers to the human tendency to construct narratives around facts.

The danger, and the essence of the narrative fallacy, comes when we believe these stories as truths, and worse yet, when we begin to accommodate and massage our facts to fit into our stories.

What starts as raw data, becomes, through our cognitive filters, misleading. Humans like to summarize and simplify. We like to find convenient and comforting patterns in data.

One story that might evolve from a cursory look at the Bobtuse Bobservations ClustrMap is
This blog has 9 loyal followers in Wellington, New Zealand.
Although an equally plausible story might be
This blog was visited by 1 person in Wellington, New Zealand who had inadvertently landed here after searching "flightless birds".
So, use data feeds from ClustrMaps or FeedBurner - or any data for that matter - to your heart's content. But, beware the seductive narrative. Resist the temptation to believe the stories you might weave around the data (e.g., see my post 100% Coverage is a Crock of Clam Juice).

11 May 2009

Is Version One a Software Chindōgu?

Chindōgu is the act - some would say art - of creating a product whose usefulness is precluded by its absurdity.

Chindōgus are not absolutely useless, since they typically solve a problem; yet in practical terms, chindōgus are much more humorous in their inherent absurdity than they are useful.

The Japanese word chindōgu means unusual tool. Chindōgu, and its inventor Kenji Kawakami, were featured on the BBC television show It'll Never Work.
How many software chindōgus are you aware of ?
Our team is consistently bewildered, confounded, and confused trying to use Version One to plan and track iterations and work tasks. This isn't a rant about Version One. Maybe Version Two will provide tangible value....who knows?

If you have a Version One success (or failure) story,

Or, if you have a Software Chindōgu to share...
Please post a comment!


Donald Norman's case studies in The Design of Everyday Things awaken us to the successes and failures of everyday things from the standpoint of usability. Software professionals involved with user interfaces would do well to read Norman's book if only to re-sensitize themselves to the user's experience.

As software professionals, we should strive to grow software that is well-thought out and cleverly usable -- not spawn software oddities suitable for chindōgu museums.

08 May 2009

Code Cleanup - Stupefyingly Satisfying

Ctrl-Alt-F is my opiate of choice -- I’m a ReSharper Code-Cleanup junkie.

Ctrl-Alt-F is ReSharper's shortcut to a magical function that transforms all orphaned variables, non-standard formatting snafus, and unneeded C# using statements into a immaculate tray of chocolate chip cookies.


It’s stupefyingly satisfying.

Thanks to Markus, I am mortally dependent on ReSharper. When I used .Net 3.5 for the first time last year, ReSharper offered several intellisense suggestions that helped me adopt the slightly tweaked C# syntax -- namely, var and object instantiation.

Whether ReSharper or CodeRush with Refactor! Pro and others, who isn’t giddy making code cleaner, more granular (one method – one job!), or more uniform readable?

We all want to make code that's
So readable, it comments itself...
uh, right?

That said, such tools create and expose preference and taste issues for agile teams.

Team Manifesto - Code Standards

I like a Team Manifesto - a living document, initiated at team formation, that converges on perfection as the team matures.

All these nit-picky refactoring and reformatting preferences should be discussed, resolved, and adopted in the Team Manifesto -- not with disappearing ink, but in stone, with well-deliberated carvings that are readily updated at the pound of a chisel.

All teams should consider discussing the refactoring/formatting tool and agree upon standards.

A few questions for the team that come to mind are:
  • Which refactoring/formatting tool to use, if any?
  • Should the team establish a template of standard options within the tool that everyone applies uniformly (e.g., naming styles, braces layout, line breaks, type member layouts)?
  • Is it okay for team members to invoke a Code-Cleanup (or analogous) on code someone else has written?
Can you think of other questions related to refactoring and coding standards that teams should address? Please post them below. Thanks!

06 May 2009

Baffle, Befuddle, & Bewilder - Obscuring Url Tokens

Got a hankering to obscure the tokens passed along in a Url?

Say there's a business case for obscuring integer accountIDs like accountID=2201343077108877660.

What if the accountID in the fictitious Url below was better off unknown to the user?
http://bobtuse.blogspot.com?accountID=2201343077108877660
Security-through-Obscurity might be just the ticket. Encryption is useful to obscure the ID from the user. What if the accountID visible to the user was accountID=f2z64wFzyfK1HWsWzCayh1mn0Sjktl080?

That is, the url in the address bar was
http://bobtuse.blogspot.com?accountID=f2z64wFzyfK1HWsWzCayh1mn0Sjktl080
Following are C# code snippets of two methods you'll need. The TokenEncode method is
public static string TokenEncode(string input)
{
key = Encoding.UTF8.GetBytes(EncryptionKey.Substring(0, 8));
var des = new DESCryptoServiceProvider();
Byte[] inputByteArray = Encoding.UTF8.GetBytes(input);
var ms = new MemoryStream();
var cs = new CryptoStream(ms, des.CreateEncryptor(key, Iv), CryptoStreamMode.Write);
cs.Write(inputByteArray, 0, inputByteArray.Length);
cs.FlushFinalBlock();
return HttpServerUtility.UrlTokenEncode(ms.ToArray());
}

The TokenDecode method is
public static string TokenDecode(string input)
{
var inputByteArray = new Byte[input.Length];
key = Encoding.UTF8.GetBytes(EncryptionKey.Substring(0, 8));
var des = new DESCryptoServiceProvider();
inputByteArray = HttpServerUtility.UrlTokenDecode(input);
var ms = new MemoryStream();
var cs = new CryptoStream(ms, des.CreateDecryptor(key, Iv), CryptoStreamMode.Write);
cs.Write(inputByteArray, 0, inputByteArray.Length);
cs.FlushFinalBlock();
Encoding encoding = Encoding.UTF8;
return encoding.GetString(ms.ToArray());
}

Also, a few class level variables that must be visible are
private static readonly string EncryptionKey = "!962Oa#ji";
private static readonly byte[] Iv = {0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF};
private static byte[] key = {};


Usage

To obscure the accountID with TokenEncode, the C# to cobble together the Url might look like
long accountId = 2201343077108877660;
string url =
string.Format("http://bobtuse.blogspot.com?accountID={0}",
EncryptionHelper.TokenEncode(accountId.ToString()));

To unscramble the DES-crypto gibberish on the other end of a post with TokenDecode, the C# might look like
long accounId = Convert.ToInt64(EncryptionHelper.TokenDecode(Request.QueryString["ID"].Trim()));

Note that TokenEncode uses the .Net methods HttpServerUtility.UrlTokenEncode and TokenDecode uses HttpServerUtility.UrlTokenDecode. Some C# code snippets I tried used Convert.ToBase64String() and Convert.FromBase64String() instead. These convert methods work until the encoded token happens to have a +/ or = in it; these characters get munged in the query string and can't be de-coded on the post pick-up without using hack like string.replace for the errant cases.

The blog TipsForDevelopers has a good post about the Difference between Convert.ToBase64String and HttpServerUtility.UrlTokenEncode.

Paste these obfuscators into your quill. The next time you're called upon to Baffle, Befuddle, & Bewilder, TokenEncode and TokenDecode will be at your ready.