The Juice

the juice.png

I was recently asked (paraphrasing) what parts of the work of software engineering do I find “juicy” so I came up with this diagram. Any software engineering task involves both developers (if only me), customers (might be a client), and the processes of design and implementation.

The “external” blue lines are where the customer potentially interacts with the developers, the output of the design, and the implementation phase (you can probably imagine how Agile fits in this.) The “internal” red lines are where the developers interact with the each other and the design and implementation phases.

From a certain perspective, the left side represents the “process” and the right side represents the “results.” Process and results should be balanced – developers may discover they require training in new skills, teams adjust based on where the team is in the process, etc. The process creates results which the developer and customer team review.

The process – results flow iterates with each result. The earlier results are produced, the better for everyone because this is where “education” occurs, for example, the developers learn more about the customer’s requirements, the customer may refine their requirements (or change them!) Both the developers and the customers learn things during iterations which in turn create adjustments in the process.

The list of items within the boxes is basically just all the stuff that I find “juicy” – the more of those items that get checked off for a project, the more excited I typically find myself regarding working on the project.

Why TDD Fails

Recently posted on Code Project:

I’m just now trying to adopt my thinking to Test Driven Development mode and I’m finding strange, inconsistent, and bizarre things happening in my thought processes and code in some ways as well. Is this pretty normal when you first try to learn TDD?

And as usual, this got me thinking.  My response:

Yes. TDD is for the birds, but even they didn’t first write tests to figure out if wings could support them, and then developed their wings.

In other words, TDD is in many cases ridiculous because it requires that you write code to test something you haven’t written yet.

The mindset for writing tests is orthogonal to writing the code you are going to test. When you do the latter, you’re thinking about abstraction, decoupling, performance, optimal structures, and, here’s the clincher, you’re thinking (or should be thinking) about how to structure the code so it can be tested.

When you’re writing the tests, you’re thinking about edge cases, parameter validation, exceptions trapping, whether the business logic is correct, and here’s the clincher, you’re thinking about how to ensure that all code paths are actually exercised.

Now I ask you, how can you test that all code paths are actually tested when you haven’t written the code?!?!?!

So of course TDD is a mind f***. It’s a different process, and it’s often a BAD process. Of course there are cases where you can write the tests first, but certainly in my experience, anything other than a very isolated piece of business logic, it doesn’t make sense. The main result of TDD ends up being that you’ve written a bunch of useless tests, and even worse, you’ve written code to meet the structure imposed by the test.

So what should TDD be then, you might ask? Well, it should be a concept of what needs to be tested – is it algorithm correctness, is it performance, is it multithreaded support, is it worth testing? Then write the code with the idea in mind of what you are wanting to test so that the code is testable, then write the tests.

Mark_Wallace on the Code Project also had an excellent response:

TDD is extremely good for two things:

0. Getting loose cannon devs on track.

We all know and have to deal with such guys, but it’s not hard to write tests with premises like “This is the name of the output module, and these are the expected outputs from it”.

— You know your inputs
— You don’t care what the processes are; that’s where you rely on other developers
— You know the outputs That Have To Result.

So write tests for it.

What TDD does is get that clear in everyone’s mind, so flying off in weird and unwanted directions is less likely to happen.

1. Forcing specs

For me, this is their primary function. Even “produce working code” is secondary.

Put it this way: It’s a way of introducing specs when the f***ing lazy management team hasn’t provided them — with the added bonus that the f***ing lazy management team has to sign off on it.

Amen.

Modern Agile: Reminds me of a Strip Club

stripclub.jpg

InfoQ recently posted an article about something called “Modern Agile” (I guess they couldn’t call it Agile Agile, or Extreme Agile) and it takes an already loosey-goosey concept to new heights of vapor-process.

Agile is modernizing. Thanks to Lean and Agile pioneers and practitioners, we now have simpler, safer, speedier ways to achieve awesome results.

While that sounds like the tag line for a vibrator rather than a software development process, what really got me was this statement:

Modern Agile has no roles, responsibilities or anointed practices.

In other words, Modern Agile is, well, nothing.  Nothing that provides you with any intelligent, meaningful, concrete suggestion for how to go about building software.

Instead, it has four guiding principles:

  1. Make People Awesome
  2. Deliver Value Continuously
  3. Make Safety a Prerequisite
  4. Experiment and Learn Rapidly

Why am I reminded of an adult entertainment club?

But back to software development.  First, can we, as professionals, please stop using the word “awesome?”

Awesome: extremely impressive or daunting; inspiring great admiration, apprehension, or fear.

Riiight.  That’s something to aspire to, eh?  Like I want (even if I could) make my peers into something that fills me with apprehension or fear.  You can’t make other people awesome, they have to figure out how to be awesome.  And given negative aspects of that definition, I’m not sure I want to go down that path.

Continuous: continuing without stopping : happening or existing without a break or interruption

Really?  If I were a customer receiving uninterrupted software updates, I would be yelling “STOP! DELIVER A USEFUL SET OF IMPROVEMENTS THAT WORKS, NOT CONSTANT TINY CHANGES.”  The exception might be a critical bug fix, but as a customer, I do NOT want to be inundated with constant software updates.

Value: usefulness or importance

There you go.  Continuous value is sort of an oxymoron, especially when what is valuable in a software delivery is often something different for each stake-holder.

Safety: the state of not being dangerous or harmful

And Modern Agile, being a vapor-process, is sooo good at explaining exactly how that’s done.

Experiment: a scientific test in which you perform a series of actions and carefully observe their effects in order to learn about something.  Something that is done as a test: something that you do to see how well or how badly it works

Absolutely.  But sadly software development is hardly scientific.

Agile is something that I’ve always considered a bit ridiculous, and Modern Agile goes to the next level: the ludicrous, the absurd.  Modern Agile sounds great, especially in this new-age feel-good world of software development, but it’s ultimately a collection of words that mean nothing in any usable sense.  Just like a strip club.

The Software Development Process – Science, Engineering, Art, or Craft?

oops-small.jpg

There is general consensus that the software development process is imperfect, sometimes grossly so, for any number of human (management, skill, communication, clarity, etc) and technological (tooling, support, documentation, reliability, etc) reasons.  And yet, when it comes to talking about software development, we apply a variety of scientific/formal terms:

  1. Almost every college / university has a Computer Science curriculum.
  2. We use terms like “software engineer” on our resumes.
  3. We use the term “art” (as in “art of software development”) to acknowledge the creative/creation process (the first volume of Donald Knuth’s The Art of Computer Programming was published in 1968)
  4. There is even a “Manifesto for Software Craftsmanship” created in 2009 (the “Further Reading” link is a lot more interesting than the Manifesto itself.)

The literature on software development is full of phrases that talk about methodologies, giving the ignorant masses, newbie programmers, managers, and even senior developers the warm fuzzy illusion that there is some repeatable process to software development that warrants words like “science” and “engineer.”  Those who recognize the loosey-goosey quality of those methodologies probably feel more comfortable describing the software development process as an “art” or a “craft”, possibly bordering on “witchcraft.”

Read the whole article on the Code Project.

 

The Clifton Manifesto

manifesto.png

Individuals and interactions and processes and tools
Working software and comprehensive documentation
Customer collaboration and contract negotiation
Responding to change and following a plan

In direct contrast to the Agile Manifesto:

Individuals and interactions over processes and tools
Working software over comprehensive documentation
Customer collaboration over contract negotiation
Responding to change over following a plan

Why?  Because the Agile Manifesto creates tension between frequently opposing forces, leading to imbalance and extremes, which is one of the reasons Agile Development fails in actual implementation.  Conversely, I prefer to find the appropriate balance between the two, as appropriate for the client and the task at hand.