Saturday, December 19, 2015

When All You Have Is a Hammer (Part Deux) - A Cry For Professionalism

A couple years ago I wrote a blog post called "When All You Have Is A Hammer, Everything Looks like a Nail".  I was bemoaning the way that software developers (including me) will sometimes use the one thing they know and avoid learning new things.  I have further come to believe that even though we start out passionate, and with a desire to learn more, and to find ways to keep getting better, many of us still periodically have days or weeks where our output decreases in quality, sometimes we even make a complete hash of things, we who perhaps might be expected to know better.  Most often it happens when developers "phone it in" for a day, a week, or a month. Maybe they've been demoralized by micro-management, or continual hectoring.  Let's be kind to people when they are in ruts, because we never know when it will be us.  Let's ask ourselves why we build bad things, and not hector others.   Somehow, our process and its outputs are no good.  Later on this will be discovered, and someone has to clean it up.  Sometimes I am the person who has to clean up my own mess, several weeks or months later, when it becomes clear my changes were a bad idea. Sometimes I am cleaning up someone else's mess.  I ought to do this without grumbling or attacking others. That's part of being a professional. But, since I have observed this category of problems over and over again, and like any hard problem in computing (naming things, being smart and good at your job without becoming an arrogant jerk), it admits of no final solutions.   But there are things we can do, and if the software you make is making the world a better place, then you should care enough to try to do your job better, every week, every month, every year.

First, begin your coding day by asking yourself if the work you're doing today matters. For some of you, that's easy.  Even if curing cancer is out of your reach, then at least increasing the effectiveness of breast cancer screening protocols counts, if you work at a place that does that.  But let's say you spend five minutes considering the business you work in and you still haven't thought of the reason why what you will do today (fix a bug, work on a feature) matters.   Here's my last line, if all else fails;   If what you do today keep your businesses (and your customer's businesses) running, then you're not only earning the dollars that feed you, and your children today, you're also helping other businesses that employ people who are hopefully going to be able to feed and clothe their children, and give those kids somewhere to sleep.  And if you like me are a regular contributor to the charities that matter, then every organization that employs the men and women who give to others, is not only doing its own work, and helping its own employees and customers, it's also, hopefully making the world a better place.  So, you're rooted now? You're ready to begin your day? You care. You are checked in fully.  This is step one to avoiding doing bad engineering work. You have to care about quality.  If you're anything like me, you need to connect all the wires up, from the battery, to the lightbulb, and do that almost daily to keep caring.

Second, all day long, when you find something stupid, that makes no sense, avoid the temptation to stop caring, and push on through, so you can close your bug-tracker ticket, and go home.  Ask the questions. Find the subject-matter experts. Engage in constructive, rational critique of the system. Don't jump into ripping it apart and rewriting it, and don't jump into "must not touch legacy code" fear mode, either. In between, find a way to make the customer's life better. First, the person who is forced by the conditions of their employment to use your software is your customer. Second, the person who signed the cheque to buy your software from your employer is your customer. That business has to succeed, to keep everybody working. Nobody succeeds until everybody succeeds.   This is the second step in avoiding making these mistakes.

Third, keep learning.  If you are stuck on Delphi 5, it's time to move up and onwards. You won't even know what all the reasons why are, until you do. That's just the nature of the game. If you are stuck in a rut, defending the rut won't get you unstuck.  Fine, your code is on a modern delphi version? Next, if all you know is Delphi, then go learn Python. If you do not know any version control tools at all other than zip, then you my friend are not a professional developer.  Go learn one now, I'll wait here.  If all you know is Subversion, go learn Mercurial. If you don't know how to automate your build, at least build a batch file and invoke msbuild and have that build your Delphi, C#, and C++ targets for you.  If you're still using the lame old solution of batch files, then level up, my friend. It's time to learn how to use FinalBuilder, or WANT. If you have a build tool but no CI server software experience, it's time to learn Jenkins (or Hudson).      If you have never done SmokeTesting, you better learn how.  A smoketest job runs on Jenkins (or Hudson) and makes sure everything that is checked into source control still builds, and runs after every single checkin.   Now you have arrived at this point, it might be a good time to notice if the unit tests you write are actually finding any bugs. Does the smoketest job go red not only for compilation failures, but also for unit test failures?   If you have zero unit test failures over 60 days, chances are that you actually have zero meaningful unit tests.  Go analyze why changes that resulted in regressions that your QA person found, were not found in the unit tests.

The more I think about the problems of "hammer-thinking", the more I think there is no real solution other than the basic patterns I see in all good engineers.  Ask why.  Grow and improve. Learn.  Add new tools to your toolbox.  Build new tools when none exist.  Never stop growing.

If you don't want to do this, you should go find a new line of work.  I'm not kidding.


Agile is Dead. Agile values have been totally lost behind the implementation.
Dave Thomas (of The Pragmatic Programmer)


  1. Nice ideas. The more open-minded we are, the better. I enjoyed for instance

    Even if I do not share the need to use FinalBuilder or other tools like Jenkins.
    If you project is clearly written, you would be able to do the whole continuous integration process in a single batch. Not only unit tests, but also integration/system tests and performance tests. With not need of external tool. Compile, run the tests, and check the results. Delphi compilation is so fast that the whole process is usually less than 10 seconds. I run the whole process locally on my dev PC, BEFORE committing. The sooner, the better. Then, the whole process is run AFTER the commit, on the build server.
    And I never use MSBUILD, which is IMHO a full bloatware (from my years writing C#)... but directly call the dcc.exe. Installing a Build server is so easy: copy the Delphi bin folder, your .bat file, install your SCM command line tool, and you are done.
    Of course, it is made easy because we use an integrated framework like our mORMot, which allows to run a set of daemons in a single process, with their own local databases, without the need to install the whole production stack. IMHO such a possibility is of much higher interest than external tooling.

    1. Batch files are good until they aren't. Can your batch file automatically detect and use the latest Delphi version, or a specified delphi version?

    2. A build system, continuos or not, does a lot more of compiling Delphi code and run it. You may need to "integrate" a lot of different things and tools. I have projects that include C++ code (both Windows and Linux), Delphi applications, Python ones. Databases need to be created, pre-popluated, and VMs need to be fired up, snapshotted, tests run for every OS supported (and VMs rolled back), then Windows installers and Linux packages built (and deployed to the proper repositories). Code and setups need to be signed with keys developers don't have access to. Sure, you could still do everything with many shell scripts - but a build system usually makes everything much easier to setup and control (and reusable too). Also its UI gives nice warnings and informations about what went wrong to all the dev team. And people in DevOps may not be programmers in all the language used, but system administators tasked with keeping everything running.

    3. LDS: All good points, thanks for expanding the point. And delphi developers SHOULD be signing their code, if they work for a commercial software company, no matter how small. And who wants to do THAT manually, right?

  2. "If you do not know any version control tools at all other than zip, then you my friend are not a professional developer. Go learn one now, I'll wait here."

    I've been a one man shop for 15 years. Zip is all I've, um, needed. I was reading "Dreaming in Code" the other day where it also asserted that if version control wasn't in place then they weren't worth working with.

    I'll go learn one... after this rev ships. :)