DaedTech

Stories about Software

By

Hidden Costs in Your Software

Editorial Note: I originally wrote this post for the NDepend blog.  Go check it out over there, if you’re so inclined.  You’ll like the posts over there if you like static analysis and philosophical discussions of software design and architecture.  Also, this week will probably consist mainly of cross posts as my wife and I are going to spend a few days in a hotel in New Orleans, taking in the spectacle of Mardi Gras.

One of the things I remember most vividly from my CIO days was the RFP process for handling spikes in demands on my group’s time.  In case you haven’t participated in this on either side, the dance involves writing up a brief project description, sending it over to a handful of software consulting firms, and getting back tentative project proposals.  I’d pick one, and work would begin.

There were a lot more documents and legalese involved, but the gist, writ small, might be something like, “we need an application that will run in our data center, take information about customers out of our proprietary database, and put it back into our CRM as notes, depending on a series of business rules.”  The response, in proposal form, would essentially be, “we’ll do that, and we think it’ll cost you about $30,000.”

This is what most people think of as the cost of a software project.  Perhaps it’s not a little, 5-figure line of business utility.  Perhaps it’s a $300,000 web or mobile application.  Perhaps it’s even a $30,000,000 enterprise workflow overhaul.  Whatever the case may be, there’s a tendency to think of software in terms of the cost of the labor necessary to write it.  The consulting firms would always base their proposals and estimates on a “blended rate” of the hourly cost of the labor.  Firms with in-house development staffs tend to reason about the cost of software projects as a function of the salaries of the folks tasked with the work.

Of course, if you’re a veteran at managing software projects and teams, you realize that there’s more to the total spend than just the cost of the labor.  No doubt you factor in the up-front and licensing cost of the tools you use to develop the software as well as the cost of the hardware on which it will eventually run.  You probably even factor in the cost of training users and operations folks, and paying maintenance programmers to keep the lights on.

But there are other, more subtle costs that I’d like to discuss — costs related to your approach to software development.  These are variable costs that depend on the nature of the code that your team is writing.

Technical Debt

To really get at the total cost of software ownership requires an understanding of the concept of technical debt.  To communicate this concept, I’ll use an analogy rather than talking about software.  Imagine that you’ve cooked dinner, and you’ve used a whole lot of different dishes and utensils, all of which are now piled haphazardly in the sink.  They’re dirty and covered with drying food debris that, left untended, will make them very hard to clean.

DirtyDishes

Read More

By

Refactoring is a Development Technique, Not a Project

Editorial note: I originally wrote this post for the NDepend blog.  Go check it out over there and stay for a while to look around.  If you like posts about code analysis, metrics, and the business of software development, you’ll like the collection of posts there.

One of the more puzzling misconceptions that I hear pertains to the topic of refactoring. I consult on a lot of legacy rescue efforts that will need to involve refactoring, and people in and around those efforts tend to think of “refactor” as “massive cleanup effort.”  I suspect this is one of those conflations that happens subconsciously.  If you actually asked some of these folks whether “refactor” and “massive cleanup effort” were synonyms, they would say no, but they never conceive of the terms in any other way during their day to day activities.

Let’s be clear.  Here is the actual definition of refactoring, per wikipedia.

Code refactoring is the process of restructuring existing computer code – changing the factoring – without changing its external behavior.

Significantly, this definition mentions nothing about the scope of the effort.  Refactoring is changing the code without changing the application’s behavior.  This means the following would be examples of refactoring, provided they changed nothing about the way the system interacted with external forces.

  • Renaming variables in a single method.
  • Adding whitespace to a class for readability.
  • Eliminating dead code.
  • Deleting code that has been commented out.
  • Breaking a large method apart into a few smaller ones.

I deliberately picked the examples above because they should be semi-understandable, even by non technical folks, and because they’re all scalable down to the tiny.  Some of these activities could be done by a developer in under a minute.  These are simple, low-effort refactorings.

Let’s now consider another definition of refactoring that can be found at Martin Fowler’s website.

Refactoring is a controlled technique for improving the design of an existing code base. Its essence is applying a series of small behavior-preserving transformations, each of which “too small to be worth doing”. However the cumulative effect of each of these transformations is quite significant.

I took the wikipedia definition and used it to suggest that refactorings could be small and low-effort.  Fowler takes it a step further and suggests that they should be small and low effort.  In fact, he suggests that they should be “too small to be worth doing.”  That’s fascinating. Read More

By

Bringing Objectivity to Clean Code

Editorial Note: I originally wrote this post for the NDepend blog.  Please go check it out over there and take a look around at the content while you’re at it.  NDepend is one of the most indispensable tools in my toolbox.  

If you want to stir up a pretty serious amount of discussion-churn, wander over to where the software developers sit and ask for a consensus definition of “clean code.”  This probably won’t start a religious war — it’s not like asking for consensus on the best programming language or development tool.  You’ll probably find a lot of enthusiastic agreement with different flavors of the same basic concept.  This is true among luminaries of the field, as quoted here on DZone, and it’s most likely to be true in any given shop.

There will be agreement on the broad concepts and inevitable debate as the points become of a finer grain.  Developers can all agree that code should be “maintainable” and “easy to read” but you might get a bit of fragmentation around subjects like variable naming or relative compactness and ‘density’ of code.  Have the developers look at a bit of code and ask them if it could be “cleaner” and you’ll probably get an array of responses, including potential disagreement and thrash.  This will become especially true if they get hung up on cosmetic particulars like indentation, bracket placement, and casing.

So where does that leave us, exactly, when asked the deceptively simple question, “is this clean code?”  Programmers can arrive at a broad consensus on how to answer that question, but not necessarily on the answer itself.  They’ll all say, “well, it’s clean if it’s readable,” but some might give a particular bit of code a thumbs up while others give it a thumbs down.  If you’re a developer, this can be fun or it can be frustrating.  If you’re a non-technical stakeholder, such as a director, project manager, tester or business analyst, it can be confusing and maddening.  “So is this code good or not!?”

Enter the Coding Standards Document

When enough people with “manager” in their title are maddened, things get done.  Most commonly, this takes the form of the iconic “coding standard.”  The coding standard makes things blissfully cut and dried.

IndustryStandard

  • Thou shalt use camelCasing.
  • Thou shalt use tabs instead of spaces.
  • Thou shalt use verbs when naming methods and nouns when naming types.
  • Thou shalt not omit curly brackets for any control flow statements.

Read More

By

Relax, Everyone’s Code Rots

Editorial note: I originally wrote this post for the NDepend blog.  Go on over and check out the original.  If you’re interested in topics like software department strategy, static analysis, and code metrics, it’ll be up your alley.  

I earn my living, or part of it, anyway, doing something very awkward.  I get called in to assess and analyze codebases for health and maintainability.  As you can no doubt imagine, this tends not to make me particularly popular with the folks who have constructed and who maintain this code.  “Who is this guy, and what does he know, anyway?” is a question that they ask, particularly when confronted with the parts of the assessment that paint the code in a less than flattering light.  And, frankly, they’re right to ask it.

scan0002

But in reality, it’s not so much about who I am and what I know as it is about properties of code bases.  Are code elements, like types and methods, larger and more complex than those of the average code base?  Is there a high degree of coupling and a low degree of cohesion?  Are the portions of the code with the highest fan-in exercised by automated tests or are they extremely risky to change?  Are there volatile parts of the code base that are touched with every commit?  And, for all of these considerations and more, are they trending better or worse?

It’s this last question that is, perhaps, most important.  And it helps me answer the question, “who are you and what do you know?”  I’m a guy who has run these types of analyses on a lot of codebases and I can see how yours stacks up and where it’s going.  And where it’s going isn’t awesome — it’s rotting.

But I’ll come back to that point later.

Read More

By

Get Good at Testing Your Own Software

There’s a conventional wisdom that says software developers can’t test their own code.  I think it’s really more intended to say that you can’t meaningfully test the behavior of software that you’ve written to behave a certain way.  The reasoning is simple enough.  If you write code with the happy path in mind, you’ll always navigate the happy path when testing it, being hoodwinked by a form of confirmation bias.

To put it more concretely, imagine that you write a piece of code that reads a spreadsheet, tabulates sums and averages, and reports these to a user.  As you build out this little application, one of the first things you’ll do is get it successfully reading the file so that you can write the other parts of the application that depend on this prerequisite.  Over the course of your development, you’ll be less likely to test all of the things that can go wrong with reading the spreadsheet because you’ll develop kind of a muscle memory of getting the import right as you move on to test the averages and sums on which you’re concentrating.  You won’t think, “what if the columns are switched around” or “what if I pass in a Word document instead of a spreadsheet?”

Because of this effect, we’re scolded not to test our own software.  That’s why QA departments exist.  They have the proper perspective and separation so as not to be blinded by their knowledge of how things are supposed to go.  But does this really mean that you can’t test your own software?  It may be that others are more naturally suited to do it, but you can certainly work to reduce the size and scope of your own blind spot so that you can be more effective in situations where circumstances press you into testing your own code.  You might be doing a passion project on the side or be the only technical member of a startup – you won’t always have a choice.

Let’s take a look at some techniques that will help you be more effective at testing software, whether written by you or someone else.  I originally wrote this post for the Infragistics blog, so click here to read about the techniques to which I’m referring.