The testers will take care of it

June 7, 2009

Just this week I was attending a webinar regarding making test organizations more efficient. I’ve been doing a lot of work with test organizations lately so I figured spending some of my time to learn something new would be worthwhile. The presentation was pretty good, and the presenter had, I think, one exceptional statement about front-loading quality. It went something to the effect of “developers should believe that the system is ready for the users when they deliver it to system test.”

Simply stated. Brilliant! The point of front loading quality is to make testing unnecessary. So, he continues to tell us this story about how he gives presentations to teams that he is consulting with and makes the above statement and then waits out the silence. A long pause, he says, before some brave soul says “we can’t do that!” (or something to the effect). At which point, having taken the bait, he then asks them “well why not?”

And the answers come pouring forth:

  1. We don’t have the skills
  2. We don’t have the environments
  3. We don’t have the tools
  4. We don’t have the time

And so on, and so on, and so on. What!?!? How is it that your developers are allowed to give these excuses for why they deliver poor quality code into the environment? And more importantly than all that, what makes a developer think that if they have these barriers to delivering quality code why testers will have any capability to do solve the problems that developers cannot.

These are false barriers. These are excuses. The testers, who find all your bugs, have test environments. The testers, who find all your bugs, have some set of tools. And testers, mind you, don’t go to college to learn how to test. By in large, testers are developers who couldn’t. Sorry to say it, but it is true. Testing is an organization usually comprised of the weakest developers and analysts. Not that it necessarily should be, but every experience I’ve had says it is.

If your developers can’t find their way past their reasons, what secret to testers have that would make what were intractable problems into tractable ones? There is no valid excuse for being incapable of delivering quality code.


No raindrop believes it is to blame for the flood

November 10, 2008

If you had a thousand defects in your product, how would you make them go away?  You’d fix them, of course, wouldn’t you?  Wouldn’t you!?!?!

And yet, here we are, staring that exact situation in the face.  A thousand open defects and growing.  Are they all show stoppers?  No, but they’re all valid defects.  Alas, the team was told to get the open inventory down.  And how could you do that? 

Well, you could fix the bugs.  This would be a reasonable conclusion if the queue wasn’t growing out of control.  If the bugs are coming in faster than they’re going out, you’re just treading water by fixing bugs.  The right thing to do would be to fix the upstream process.  If you stopped making so many bugs, the queue would stop growing and then you could fix the problems and the queue would go away.  That’s the RIGHT answer.

I didn’t realize there was a more wrong answer than trying to tackle the queue without solving for the root cause.  But there is.  Today I was told that rather than fixing the root cause of bugs and rather than fixing the bugs in the queue that we’d simply close things in the queue.  Unfixed!  Unresolved! 

You heard me right, just close them!  The reasoning is, some bugs just aren’t worth fixing.  I could grant you that this appears true on the surface.  If the bug’s potential financial impact is $100 each time it occurs and it costs $100,000 to fix it, then the ROI doesn’t seem to play out.  You’d have to have that bug pop up 1000 times.  So you skip that bug.  Seems fair.  Well what about the next bug that costs you $100, or the next one, or the next one?  Do you just skip them all?

We’re on a real roll now.  Suddenly bugs with a 5 or 10 year ROI aren’t getting done.  Maybe bugs that have a 3 year ROI are being skipped.  It really isn’t about that one bug you skipped.  It’s about the backwards philosophy that the issue can be looked at one bug at a time.  If this one isn’t so bad, then the next one just like it isn’t so bad.

Consider my phone company.  I use Vonage.  They’re not the greatest, I’ll admit, and I put up with a lot of poor phone quality.  The thing is, every once in a while, even with Verizon, you get a crappy connection.  You can’t hear them or they can’t hear you.  Whatever it is, you hang up frustrated and call back and it’s better.  But you’d be annoyed if at first it was a poor call, and then the phone wasn’t ringing and then the call got dropped and then your caller id worked intermittently, and so on.  Maybe one thing by itself is just annoying, but put them all together…

Well, what’s so different about bugs?  Sometimes you get bug A, which is annoying, but it is transient or you work around it, or whatever.  And then there’s bug B hiding right behind it.  And bug C and D and so on and so on.

Sure, by itself I can live with one minor but annoying bug.  Two, and I’m getting frustrated.  Three or more…  You see how it goes.  Dealing with a bug in isolation of all the others out there misses the point.  It’s not that I can’t live with this bug or that but, but I can’t live with all the bugs.  So closing them surely gets them out of the queue, but it doesn’t fix them or make them go away!  They’re still there.  Waiting to come back.  Waiting to be reported again.  Waiting in the wings to annoy someone and bring down the perception of your product’s quality.

Now, maybe you might conclude that this one bug is not worth fixing, but when you’re making that decision, consider this:  no raindrop believes it is to blame for the flood.  And yet, people drown in floods all the time.


Why errorproof when you can double-check?

April 28, 2008

OK, so riddle me this… if you were a programmer and were writing some software would you:

A) make it possible for the user to screw up using the software and then spit out annoying error messages after the fact?

OR

B) make it so that the user did the right thing in the first place?

Please tell me you answered B.  I know you didn’t.  I wish you did, but I know you didn’t.  Why?  I have no idea why.  That’s what makes it a rant!

Just today I was talking with a group of folks who had developed a template.  It was a generally good template, but they sent it along with another tool that checks the template to see if users have filled it in properly.  So, let me get this straight… we coded a template that the users are ALLOWED to screw up.  Then we coded another tool to check to see if the users screwed it up!?!?

If you are in the position to prevent the error in the first place, why wouldn’t you?  And, I’d argue, if you can write a tool to detect the screw up – ie, it is possible to programmatically figure out that the template is wrong, so it requires no great amount of human intelligence - then you MUST understand enough about the system that you could have coded it in such a manner that the users didn’t screw it up in the first place.

Call it front end edits, call it whatever, but why in gods name would you allow your user to do a bad thing and then punish them later for it?  It just doesn’t make any sense!

I get that some things are hard to error proof.  Manual processes are hard to errorproof.  People want to do the wrong thing for some crazy reason.  They like subverting processes.  But, why, oh why, would you allow the same thing in software?  It is one place where you can completely block a user from doing the wrong thing.  And yet… you develop a template and a governance tool to make sure people are using the template right?  Just make it so the template gets used right and throw away the stupid governance garbage!


Build it or buy it?

March 5, 2008

Oftentimes this is a question when it comes to software itself.  People are always trying to determine whether they should build a given application or buy something off the shelf and just use it.  A great blog entry speaks to the exact issue.  There is a school of thought that software should fit the process and not the other way around.

I’m questioning if there’s another level this can be extended to.  Do you “buy” a software development process (SDP) or build your own?  There’s a broad range of SDPs out there today so it certainly would be easy to take one and use it, right?  Why would you ever start from scratch and roll your own?

For one, I think that most large processes are freakish monoliths that are more marvels (and I mean “marvel” in the least generous of terms) of engineering than practical applications.  CMM, for example, though not an SDP per se, is a great example.  I have been on a team who was attempting to reach CMM level 3.  We abandoned the effort because it killed our flexibility.  Now, it may have been a lack of creativity on our part, or it just may be that the process was more demanding than we needed to be effective.  That team of folks had a very lean development process and insanely low defect rates.  The system of about 100,000 lines of code had 12 known low-criticality defects.  It was a medical device, so having defects was a big issue.  And yet, we didn’t benefit from having a bulkier process for getting our work done.  Defect containment rates were consistently 100% and defects found during test were usually very minimal.  The existing process was very, very sound.

And yet, someone thought, “why are we using our own process?  There’s one out there we could use.”  Can and should are two different things.  So here I am at my new company, almost 12 years later and I’m hearing “we should switch to Agile.”  Putting aside my rants re: Agile in general, what is driving us to even think about it? 

Do we have problems with our development?  Sure, who doesn’t. 

Do we have defect rates we don’t like?  Sure. 

Do we have schedules we don’t like?  Sure. 

But we have a process which the company has been using for years.  How is it we are unwilling to understand what we have but willing to buy what someone else is selling?  If we don’t understand what drives the performance of the current process, what makes us think that going “Agile” is going to solve any of our problems.  What if our current process is good, but the key driver of performance is the below-average employees we hired?  An Agile implementation would suffer greatly in that reality, based on recommendations from Barry Boehm’s work.

A favorite refrain in the Six Sigma world (at least the one I’m in) is to “not boil the ocean” which has led us to attempt to chip away at the efficiency and quality issues in the organization.  Yet the process which our customer sees is from request to installed functionality.  Why are we fixing just software design or coding or unit testing?  If we understood the real end-to-end process we could optimize across the hand-offs and truly make a difference.

There are no silver bullets.  Are we “buying” a process because we’ve given up and we don’t understand the one we have? 

Are you?


Partner or Customer?

February 28, 2008

This is often a point of contention in the systems world.  Is the business a customer who we serve or a partner who we work together with?  One can see how we’ve made the bad shift to calling them business “partners.”  Partnerships are a peer relationships.  We are equal, we have a say in what happens to the system because we know best.  We have goals and needs that matter as much as the businesses’ goals.

This is so horrifically wrong I don’t even know where to begin!  First off, what’s the difference?

Partners work out their differences together.  Think of a husband and wife team working out their financial decisions.  They’re equals and have to agree on what matters to them collectively.  “Partners” also suggests we are stuck with each other, so we better figure out how to work together.

Customers, on the other hand, are always right.  We serve customers needs.  They tell us what they want and we do it.  By comparison, when we are customers we are not tied to one supplier.  We can choose our supplier which forces all of them to be competitive for our business or risk going out of business.

Who exactly wants a partnership?  I believe it is Systems who convinces the business this is in their best interest.  Why?  Systems people are generally relatively smart and they consider what they do to be highly specialized and so want to be listened to and have their advice taken.  In some ways they’re a lot like doctors.  We hold knowledge that other people don’t want to acquire or can’t acquire.  Just like it frustrates the hell out of your doctor when you come in and tell him/her what’s wrong with you, it makes Systems people really mad when you tell them how to build their systems.  After all, we have grand visions of beautiful works of engineering.  We are arrogant. 

Arrogant people do not make good partners.

Why does business agree to a partnership?!?  On the surface, it seems to make sense.  The thinking goes something like “if we have a partnership then we’ll get to see behind the curtain and finally understand why it costs a bazillion dollars to do anything.”  Again, like going to your doctor, if it only took you like 2 minutes to diagnose your own ailment so why does a doctor’s visit cost so much?  If the business can imagine the solution as a web page or two, why does it cost $5 million?  When a business has been unhappy with their systems costs for a long time, they enter into the “partnership” in hopes that once they find out what’s going on they’ll finally be able to put an end to it.  Stupid move.  It’s like giving an alcoholic a drink!  Once we’ve had that sweet, sweet taste of telling you how we can’t do your project because we need to re-architect this batch program or that web service it’s all over. 

This is why a business should always refer to systems (even internal systems groups) as a supplier.  And Systems, we should get used to calling our business a customer.  Like it or no, we are here to serve.  There is nothing wrong with serving our business!  Our business is the reason we exist.  Our business pays our salaries.  If you want to have the right to recommend something to your customer, you must first serve them faithfully so they know they can trust you. 

I don’t go to a new mechanic and immediately do all the services they recommend during an oil change!  If you do, seek help.  I don’t trust them yet to tell me what I need because I know they’re trying to sell me something.  After going to the same place a long time and having them talk me out of an expensive service I propose that I don’t need, then I’ll know that they are trustworthy and start taking their advice.

Most importantly, calling your business a customer will remind you of an important fact.  Systems is expendable.  As I’ve said in a previous post, we are largely cost centers and therefore it is in the best interest of the business to minimize the expense.  If you start thinking you are a partner, your costs will go up, you will get comfortable and settle in for a long, cozy relationship.  And then, one day, when you don’t expect it, the business will hire an outsourcing firm to do the work instead and FIRE YOU ALL!  Just because you are an internal systems group doesn’t mean you don’t have to be competitive with the real world.  If you can diagnose your own ailment, you can bet folks in the business are smart enough to figure out that their own systems group has become a waste of money.


How factories ruined efficient software development

February 21, 2008

The vision of a factory of workers churning out code has ruined efficient software development.  At first one might argue that it’s because thought workers don’t work that way, but I think it’s something much more simple.  Consider what a real factory does.  It takes some input and manipulates it in some way in a series of steps to produce an output.  Whether it’s a machine doing the work or a line of people, each step has someone/something processing an input and spitting out an output.  Each person or machine is highly specialized to do just that task and do it efficiently.

 The factory system is a pipeline where each person has a stream of inputs coming in and manipulates each into a stream of outputs going out.  If one person in the stream were to stop working on their inputs everything down the line from them would simply run out of work to do.  The resources would be idled, and those expensive resources (be it people or machines) would still have to be paid for but wouldn’t be producing anything. 

Factories are highly tuned to never allow those bottlenecks to happen so that nothing goes idle for long, if at all.  It’s easy to watch the widgets move through the system and it’s easy to see where they back up so it is easy to fix.  And here I bet you’re thinking I’m going to say something cliche’ like “you can’t see software widgets” or “because each part needs custom manipulation there are always backups in the system.”  The answer is no, I’m not.

The reason the factory model doesn’t run efficiently in software development is because there is too little going through the queue, not too much.  And Parkinson’s Law (“work expands to fill the time allotted”) takes care of the rest…

I think software does produce the equivalent of widgets.  Sure, they’re custom widgets, but they get similar types of work done at each step:

  • A worker writes a requirement and passes it along…
  • … to an analyst who writes up the change to the system and sends it to…
  • … a developer who codes the changes and it goes to…
  • … a tester who validates the change and finally…
  • … it gets dropped into prod, or batched up and shipped off to production.

What doesn’t happen, however, is work doesn’t come in a nice flow.  The users don’t specify one requirement to be worked on, they specify hundreds or thousands which all get batched up and given to an analyst who manipulates them all until they’re ready for the next step and so on.  And what’s happening downstream?  Well, projects are like mini factories that pop up within the company.  At least, in a matrix staffed organization like I work in they do.  A team of people is selected to become the factory for the duration of the project and then they’re disbanded and reformed into new factories and so on.  So when you put your factory together, what happens if you have to batch all your processing all the way through?  It wastes resources.  While the analyst is working, the developer and tester are doing pretty much nothing.  And the requirements guy is just sitting around, his job pretty much being over.

Now honestly, there’s no need for it to be so inefficient.  It only gets that way because of turf wars.  If I want to run a project I have to put my hands on all the resources and scream “mine! mine! no touch!” or else someone else will swipe one of the resources I’ll need eventually and then what will I do when I get to that point?  So instead, I allocate an analyst and a developer and a tester at the beginning of the project and they sit around and do pretty much nothing until the requirements guy finally gets through his work.  Where I work, we’ll allow resources to be split across projects, but the rule of thumb is 2 or 3 projects max, so each project has to pay for 1/3 to 1/2 of the resource’s time regardless of what the resource does or doesn’t do.  Thumb twiddling, surfing the Internet and making trades in your virtual baseball league? 20 hours billed to the project.

And here you’re thinking that I’d say “Agile is the answer!”  And no, I’m not going to say that.  What I will say is that specialization is the mistake.  Highly specialized people make sense when there’s a pipeline of work to be done.  In a factory, there will always be another widget coming down the line for you to manipulate.  In a small company people take on many jobs because it’d be inefficient to have some guy whose job it is to just package the releases if you only put out one or two releases a year.  And that’s what these dynamically generated factories are: itty-bitty little companies inside bigger companies.

What does make sense is to build up the capability to queue work in software development.  Requirements people should churn out small requirements documents that are easily absorbed by a programmer/analyst (just one person) who picks it up and works on it until s/he’s done and it goes off to testing to be queued up there and dumped into the nearest available release.  Yes, Agile is a bit like this, but clearly it’s achievable without Agile.  I might even argue that what Agile found was that by ridding itself of highly specialized roles (like Architects and Analysts) that you could achieve efficiency.  The rest of the “people are smart, motivated and well intentioned” philosophy can be skipped.  Mediocre, mostly lazy people can still produce results if work isn’t allowed to expand forever.  And believe me, if you’re the only guy in the factory and things aren’t coming out the other end, it’s pretty clear who’s at fault.

UPDATE:  I was looking at some manufacturing blogs re: LEAN Six Sigma recently and discovered (no suprise here) that manufacturing already uses this model.  It’s called “one piece flow.”  The inefficient version is called “mass production.”


The value of everything, the cost of nothing

December 27, 2007

I used to work for a team who had great software quality.  I’m defining software quality as the number of bugs making it into production in this case.  Said quality came at an enormous cost, one which our business partners used to complain non-stop about.  It became a joke – “we don’t show up for less than a year and a million dollars.”

Bothered by the apparent disconnect between what the business wanted and what systems was offering, I proposed that we (I’ll paraphrase) “back off on some of the quality stuff and take the risk that something might go wrong for a significantly cheaper price.”  Sadly, I got laughed out of the room.  I know that I was not wrong.  You don’t need to have been around long to experience an arrogant system’s organization who thinks they know better than the business on what the business wants.

Would you put up with this in the real world?  I think not.  What if you came into a grocery store looking for a can of green beans and I as the cashier said “I’d like to sell you that basic can of green beans, but it wouldn’t be right for me to do so.  What you really want, but didn’t know it, was a machine that will automatically deliver you green beans right to your door before you even ask.  Sure, the can of green beans only costs $1.09, but you’re really going to like my machine for $250,000!” … “what do you mean you don’t want to spend two-hundred fifty thousand dollars?  I’m sorry, then I can’t help you.”  Sounds like hyperbole?  It isn’t in software development.  It’s part of the reason Agile is appealing to businesses – the business gets the last say in EVERYTHING.  I believe in that philosophy (I just don’t think you need to go Agile to live it).  It is the job of all good software development organizations to deliver what the business needs.  If you aren’t doing that get out of the software business.

Accept this reality (with the exception of software development companies):  YOU ARE A COST CENTER, NOT A PROFIT CENTER!  If the company could figure out how to do business without paying for your software services they would!  Most companies are NOT software companies and they need the software to a) do the job they need done and b) cost as little money as possible.  They don’t want to spend money on you; they don’t particularly like you.  They show how much they dislike you by outsourcing or off-shoring you.

This is not a bad thing.  It just is.  That’s the way the world is - maximize profit, minimize cost.  And frankly, you are and always will be a cost.  Now that you understand how I feel about software developers, and I was/am one, you can see why I might suggest that we back off on some of this quality stuff and take the risk of some defects.

I could build you an invincible car probably that would run forever.  You just wouldn’t want to afford it.  To get to that kind of quality would cost more than you’d reasonably pay for a vehicle.  The same is true of software development.  Users can and will accept a certain number of defects in exchange for a reasonable cost.  If you haven’t seen this curve before, it’s not to any particular scale, but it represents the law of diminishing returns when it comes to software quality.

The Quality/Cost Curve

 Essentially, at some point, you pay exponentially more and more to get smaller and smaller increments of quality improvement in software.  For each company, there is somewhere along this curve where the trade-off is no longer worth it.  Sure, if you’re working on the space shuttle or a medical device, very, very few defects are acceptable.  Defects on a project like that kill people.  But what about defects that could be resolved without anyone dying or losing their life savings?  I’d rather not have them, but if it is detectable and reversible I’d probably be OK as long as you eventually fixed it.  And then there are certain things which are quirky or annoying but don’t do any real damage ever.  Frankly, for most purposes, who cares?

And this is exactly where I was coming from when I said we should back off on some quality activities.  Clearly, though our quality was excellent, we were too far up the curve and it was costing too much to get that level of quality.  I know that the development process had gotten to where it was because with each mistake the team added something to the development process to assure that “it never happened again.”  Now, for a given project that “thing” might be irrelevant, but we’d be damned if it snuck in somehow.  We always had some quality activity to assure that a given mistake was never, ever repeated.  In my opinion, these are exactly the things you should back off on.  It was unclear if the mistake could even be made again, so the quality activity wasn’t necessarily adding quality.  Nobody had measured it and nobody knew for sure, but they were deathly afraid to find out that they might miss that same something again.

Do not be afraid to test the limits and find where the right trade off for the customer’s needs are.  There is a certain quality they need, but there also is a cost they aren’t willing to pay.  In terms of a Kano analysis, over optimizing for cost suggests you believe that quality is a primary satisfier of your customers, and it is likely to be a must be.  You have to have a certain amount of quality, but more of it isn’t going to make your customers that much happier.


Caught between a rock and a hard place

December 21, 2007

Yesterday was just another day in the office and another bombardment with Agile as the silver bullet to all our problems.  Usually I just sit quietly and zone out when someone gets on the “Agile is going to solve all our problems” soapbox.  Unfortunately, after being subjected to a highly contrived team exercise to show how waterfall development was bad and Agile development is good and then being forced to listen as not one, but three, of my otherwise highly respectable peers sang the praises of Agile I could take it no more.

“This is ridiculous!”  I blurted out.  Yes, seriously.  So, in another article I shall talk about what would be considered career suicide, but I could take it no more.  One thing I have insisted upon (probably to my detriment) is that I walk out of work with my integrity intact.

First off, my comments went to something along the lines of “you are treating Agile like it’s some sort of new religion that you’ve all just found” and “I haven’t heard one bit of critical analysis about Agile’s potential weaknesses” and finally “everything you have said that is great about Agile can be accomplished in a waterfall-like methodology.”  In all fairness, pretty much everyone who compares Agile to waterfall insists on looking at the far end of the spectrum.

A Process Spectrum

This is my proposed software development spectrum.  On one end of the spectrum we have what most people compare against when they refer to “waterfall”.  I’d say the company I work for and the US Government falls into this school of thought – documentation for the sake of documentation.  On the other side of the spectrum, which people pretty much universally dismissed, is “cowboy coding” wherein each developer simply does what s/he thinks is right.

So, let’s talk about what’s out there on the far left:

  1. An insane amount of documentation, so maintaining the documents rather than the software becomes the job
  2. Crazy project schedules that are totally predictable but completely unreasonable due to all the overhead
  3. So much rigidity that change results in predictable pain as you are wrung through the change control process

Out on the far right we have:

  1. A complete lack of any documentation, so software maintenance is a nightmare
  2. Crazy project schedules that are totally unpredictable yet appear at first to be completely reasonable due to a lack of any learning from past experience
  3. So little rigidity that change results in suprise pain inflicted by unexpected consequences

At either end, the same problems manifest themselves in a very different way.  I’m sure the list could go on and on. 

So what’s in the middle?  Agile?  Yes.  Waterfall?  Also yes.  How can this be?  What really is in the middle is common sense.  I realize that if common sense were so common you wouldn’t be reading this, but I lack a better name for it.  I’d propose that “good” Agile exists somewhere just to the right of center (a little more towards “people are smart and make good decisions”) and waterfall exists somewhere just to the left of center (a little more towards Ronald Regan and “trust but verify”).

Here is why I believe this is true.  For every Agile “benefit” that I’ve heard I can find you a reasonable waterfall equivalent advantage / disadvantage.  I’ll go through a few (just to make my point) in the format: Agile “advantage” -> Waterfall equivalent.

  1. Regular delivery of business value -> phased development.  AKA multi-stream waterfall OR simply put “do smaller projects.”
  2. Just in time requirements -> again, phased development.  Only ask for what you need.  This is a problem with requirements elicitation and prioritization, not waterfall.
  3. “Right” documentation -> “reasonable” analysis and design documents.  It is imperative you recognize that documentation is not written just to produce documentation.  It only serves the purpose to prove the design correct before coding.
  4. Group decision making, pair programming, etc. -> peer review.  Two heads are better than one, I’ll agree.  I’ve already ranted about decision by committee before.  Compromise is not always a good thing.
  5. Team defines the development process -> a smart person defines the development process.  Don’t get a moron to define your development process; you end up on the far left of the spectrum.  Plus one process means you can make comparative measures.  Note, you should read my prior rant against broad standardization to understand when it is appropriate and when it isn’t.

Also, we should talk about equivalent costs of Agile vs. waterfall.  This time, in the format: waterfall “cost” -> equivalent or replaced Agile cost.

  1. Time spent designing/documenting -> refactoring.  Guess what folks, no client is paying you to rewrite code you screwed up.  It’s not a feature, it’s a fault.

I think Barry Boehm got it right when he laid out rules for determining Agile vs. waterfall.  I’m writing a blog and not a secondary research paper, so I’m going to reference wikipedia because I can’t be bothered to look up the original/credible source.  Fortunately for me, the wikipedia article does, so if someone quoted him improperly, take some time and update wikipedia for all our sakes.

Based on all I’ve learned to-date, I’d say the decision on which way to go comes down to one thing: do you believe that people inherently are smart and motivated or average and lazy?  Everything I know says that people tend towards the second.  Reality check, IQ is known to be normally distributed and only 3.3 percent of people have an IQ of 130-132 (depending on the test) or above.  The odds of you running into a truly smart person aren’t good and even worse if you want a smart and motivated person.  Leaning towards document nuts (don’t go to far mind you) is the cynical view of the world.  It doesn’t mean that great things can’t happen all the way out on the right in cowboy coding land, but the odds are against you.  On the upside, if you are cynical the “worst” thing that ever happens is you are pleasantly surprised.

Maybe someday soon I’ll post the basic waterfall model that I observed work really well because it used an enormous amount of common sense in the process creation and yet I insisted that each phase be finished before moving on to the next phase.  Don’t go claiming that I had stumbled upon Agile development and have simply misidentified it if I ever do post it; you’d be wrong.  My core nature tends towards “document nuts.”  It wasn’t until I got to the company I’m at now that I realized someone could take it too far.


K.I.S.S. Off

December 7, 2007

I hate KISS (Keep It Simple, Stupid)!  It’s possibly the world’s WORST advice ever given about software design and development.  First of all, I take exception at being called stupid.  I am not a moron, and most of the people I have worked with (whether they are good at their jobs or not aside) are not idiots.  Who the heck gives advice by first verbally abusing the person that you gave the advice to?  Oh, sure, I want to take advice from a person who has resorted to name calling.

Secondly, I take exception with the world “simple.”  Define simple.  Let me help.  Here’s a snippet from dictionary.com:

1. easy to understand, deal with, use, etc.: a simple matter; simple tools.
2. not elaborate or artificial; plain: a simple style.
3. not ornate or luxurious; unadorned: a simple gown.
4. unaffected; unassuming; modest: a simple manner.
5. not complicated: a simple design.
6. not complex or compound; single.
7. occurring or considered alone; mere; bare: the simple truth; a simple fact.
8. free of deceit or guile; sincere; unconditional: a frank, simple answer.
9. common or ordinary: a simple soldier.
10. not grand or sophisticated; unpretentious: a simple way of life.
11. humble or lowly: simple folk.
12. inconsequential or rudimentary.

Which one of these terms works for you to describe your code?  “Common or ordinary,” perhaps?  Or do you prefer “inconsequential or rudimentary?”  Of course, you’d probably pick “easy to understand, deal with, use, etc.”  Ok, here’s a handsaw, go cut me some boards to build a house.  It’s simple after all, so by the K.I.S.S. philosophy this is what you ought to be using to get the job done.  Forget a saw mill – it’s too complicated!

The problem with simple is that it means too many things to too many people.  Simple is subjective.  Simple isn’t simple to define or pick out.  Definition is in the eye of the beholder.

How about a practical example?  I worked on a team at the start of my career that developed software for the Ortho Autovue (check it out here if you’re curious: Ortho Autovue).  It was my first job out of college, and my mentor was the most senior member of the team.  He is a great guy; I haven’t talked to him in years but I loved working with him.  He was the epitome of the grumpy old (I’m sure he won’t take offense) programmer.  He was eccentric.  We worked in a small building, and he loved to play his music loud enough in his office that I could hear it in mine.  Yes, I had a real office with a door I could close and a window I could open!  How I miss those days when I’m sitting in my cost-saving crappy cube.  He loved to curse at the code, a habit that I picked up and took years to train myself out of once I didn’t have the privacy of an office anymore.  And for all his coding ability, the only shortcoming I can think of was that he was a fan of KISS.  He told it to me first, and it’s the one thing that I learned to disagree with him about.

His idea of KISS was code readability.  Could the average idiot pick it up and understand what he was doing?  That was KISS to him.  And so when he had to deal with translating multiple values into a single value, his choice was a giant if..then..else statement or nested if..then..elses.  It might go on for pages and pages.  Why?  Well, to him it followed the KISS philosophy.  My solution to the same problem was an N-dimensional array.  Simply reference the cell you want using the inputs as indices into the array and ta-da!

His code might be:

int TranslateValue(int X1, int X2) {
        if (X1 == 1) {
              if (X2 == 1) {return 1;}
             else if (X2 == 2) {return 3;}
            else if  (X2 == 3) {return 1;}
       } else {
             if (X2 == 1) {return 6;} ...

Easy to read, sure.  Simple?  I think you’d have to agree that it is by some definition.  Good?  Not so much.  How about my solution?

int TranslateValue(int X1, int X2, int LookupTable[][10]) {
    return (LookupTable[X1][X2]));
 }

Better?  I think so.  Simple?  There’s that eye of the beholder thing again.  In my opinion, this is a much better solution.  It’s a data driven approach.  You can’t tell from the code what the any combination of X1, X2 will return, but it’s easy to expand the function to return new values, can work for any array passed in (provided it’s second dimension is 10 elements in this really basic example), and allows for the lookup table to be read from a file or modified on the fly.  It isn’t all hard coded.  This still isn’t exactly what you’d call difficult code.  It works (I didn’t compile it and haven’t coded C in a long time so it might not compile), it’s easy to understand (even if you might have to look in a different place to understand the values in the lookup table), and above all it’s a more elegant solution.  It does everything that the giant if..then..else chain does and then some!

So, what if he was doing more than returning the value based upon examining two other values?  What if he was executing a bunch of code that had side-effects?  Then my solution no longer works, right?  WRONG!  Instead I can make the table a two dimensional array of function pointers.  Sure, function pointers scare the heck out of most people, but they are extremely powerful (compare handsaw vs. saw mill).  In his giant if-then-else he’d either be forced to copy and paste code or write functions to be called.  I still have to write functions, but I maintain the ability to read from a file (say I was using functions by name in a DLL) or change the lookup table on the fly.

Now, I will admit there are non-simple things people do in code.  I think they’re best described as anti-patterns (http://en.wikipedia.org/wiki/Anti-pattern).  Things that you do because you think they’ll be super-cool and end up handcuffing you rather than freeing you like you imagined they would.

But simple… simple is a terrible word that encourages people to write code that needs lots of maintenance every time something changes in order to provide readability or some other perceived benefit instead of doing something elegant, something so “simple” that nobody would believe it’d work. 

Another great example of the right kind of simple is Ethernet.  Prior to Ethernet you had managed networks like token-ring where each computer got a turn on the network.  It required token passing and resulted in a sluggish network whenever the size of the network grew because the token had to be passed around in case any computer wanted to do something.  Ethernet was a kick in the teeth to token-ring.  Instead of coordinating traffic, Ethernet did the most beautifully simple thing possible.  It’s was called Aloha or CSMA/CD (carrier select multiple access/collision detect). Basically:

  1. Listen.  If no one is talking on the network at the immediate moment, go!  If they are, wait a short random amount of time and then listen again.
  2. Send your data and listen at the same time.
  3. If what you hear doesn’t sound like what you sent, your data collided with someone else’s.  Wait a short random amount of time and start over.

It’s fantastic!  It’s brilliant!  It’s unbelievably super-simple.  No coordination, no need to manage the network.  Pure “chaos” with just 3 simple steps works really well!

So the next time someone else tells you to K.I.S.S., I think you should tell them to K.I.S.S-off.  Do the right thing and build the beautiful, elegant solution that’s so simple nobody can believe it works and is adaptable to change.  Don’t succumb to mediocrity.