Antiseptic Coding

Prior to Sir Joseph Lister’s research and advocation of clean surgeries, surgical culture was embodied by: “Surgeons of the time referred to the ‘good old surgical stink’ and took pride in the accumulated stains on their unwashed operating gowns as a display of their experience.”

Even today’s Neonatal Intensive Care Units require visitors to scrub upon entry. No exceptions are allowed, even if you scrubbed yesterday. Scrubbing shall occur on entry – every – single – time.

Guess what; this takes time & money! And it’s a proven technique that ensures patient survival and long-term success. But then, these are dedicated, committed professionals to ensuring success.

Are there antiseptic coding practices that can be employed? First of all, consider the definition of “septic” – infected with bacteria. The key is ‘infected’. There’s good bacteria & not-so-good bacteria. The same can be stated for processes, code & cultures.

One can posit that without a culture of constantly improving software development, secure code is a fantasy. In other words, prior to the world of surgery came to adapt sterile techniques, people just died over and over. Many security vulnerabilities can be traced back to sloppy work. Consider this list of simple, low-cost techniques that can improve code quality & security:

1. Compiler warnings are free. And helpful. And automated. A culture that strives to eliminate warnings has an incredible safety net in that as soon as a new warning occurs, it is very prominent! Consider this the most rudimentary static analysis tool.

2. Elimination of duplicated code. Once a defect is identified, fixing it once and for all makes sense. If eliminating the duplication is an insurmountable challenge, you have very big problems beyond just code.

3. Training is essential. Secure coding instruction is becoming popular. A significant population of software developers don’t have the slightest idea of what constitutes secure coding practices. Security should be designed into the code, not patched on as an afterthought.

4. Ensure your team has a professional culture that demands quality software. Consider the hiring of a plumber that leaves behind a dripping faucet; he cannot pass this off as the customer having exceedingly high expectations. Do you expect your IRA software to be high quality? Medical imaging software to be high quality? Gasoline pump credit card software to charge correctly? Perhaps one needs to consider bugs as ‘good old surgical stink’…

This is just a starting point, time to get moving!

Antiseptic Coding

Part 2 of 3 – Rote Learning Reduces Team Peformance

How can rote learning be characterized?

  • It’s a single source of truth
  • The “Master” holds the truth until the minion is anointed as new master
  • Mastery takes a very long time to achieve
  • Mastery demands deep understanding

Contrast this with the Agile Manifesto, whereby the team is encouraged to respond to change. In today’s world, change seems to be a frequent occurrence. Even small, incremental changes have a large cumulative affect over time. Motivated, empowered, confident individuals are well suited to manage the tumult.

This frequency of change often precludes a single master’s ability to stay on top of everything. Remember, the master cannot make a mistake. This places an incredible burden on the master to retain the infallible status. One strategy would be for the master to defer action (new learning) until instructed from their superiors. Basically, when the CEO determines it’s time to update to Windows Vista, then that’s a good time to do so.

Finally, consider the risks a student takes in that they endeavor to not disappoint the master. Agile assumes that lessons are learned from experiments. Note that experiments may “fail”, rendering a potential loss of student esteem. (Many folks are of the opinion that one learns from experiments so a failed experiment isn’t bad.)

Obviously, I take a dim view of rote learning. However, if one’s primary education is rooted in rote learning, there may be baggage that precludes active, incremental learning assumed by the Agile Manifesto authors. And by your management team.

Part 2 of 3 – Rote Learning Reduces Team Peformance

Part 1 of 3: How to Lower Team Performance

The Agile Manifesto changed software development. Reconciling that with the real world has some interesting mis-matches. This is the 1st of several observed in the laboratory of life.

The Agile Manifesto was put together by a set of Americans and a couple of Englishmen. Arguably, they have some homogeneity, contrasted with have women or someone of a vastly different cultural background. It’s natural these guys would feel it’s reasonable to have strong opinions, discuss at reasonably loud levels, work independently, take even small risks, etc. Somewhat fitting in the notion of a traditional John Wayne role model.

Gert Hofstede created a set of cultural dimensions that allow the comparison of national cultures. This work is used by many folks working in international domains. We are all familiar with the notion of faux pas’s that just make you look like a total dummy when assuming your behavior is OK in all countries.

So do you have anyone on your team that comes from another country? How do they compare to yours? This website: http://geert-hofstede.com/countries.html has a comparison tool for these cultural dimensions. Consider how your team members may or may not mesh on the dimensions assumed in the Agile Manifesto. The Manifesto relies greatly on personal conversations & interactions, not documents & emails.

Consider quiet folks, such as introverts. Some cultures are considered to be introverted. (I’m of 100% Finnish ancestry and arguably fit this category.) Let’s consider a quote from Quiet, The Power of Introverts in a World That Can’t Stop Talking by Susan Cain:

“Many Asian cultures are team-oriented, but not in the way that Westerners think of teams. Individuals in Asia see themselves as part of a greater whole — whether family, corporation , or community — and place tremendous value on harmony within their group. They often subordinate their own desires to the group’s interests, accepting their place in the hierarchy.”

Not the cultural emphasis on harmony: this quiet behavior may be interpreted as introversion by rough & rowdy Americans. Americans tend to be impatient and will have “elevated” conversations to quickly resolve to a solution. We don’t mind directly challenging each other and having to respond in kind. Folks such as Jack & Susy Welch have written that successful teams must be candid with each other. In their opinion, honesty is critical for team success.

So here’s the ‘so what’: what are you going to do about the cultural impedances that retard your teams performance?

Part 1 of 3: How to Lower Team Performance

Driving Development Team Improvements

Whom writes better software: a software company that sells a collection of individual products or integrated products & services such as Microsoft,  Apple or Ford?

Companies that offer integrated products learn from each teams: what works, next best ideas, failures, etc. There simply is so much interaction, it’s so natural, its like breathing. Conversely, individual product managers often have narrow, silo’d incentives. It’s all about the here and now. How can their executive management affect shared knowledge, growth, risk reduction in light of such resistance?

One thought is to rotate individuals between teams for as long as a year at a time. A developer, say “Joe”, drops what he’s doing and reports to a new team. His position is back-filled by another developer from another team. The time duration must be material: 6 or more months – enough to become a part of the new team and really learn from the experience. Upon Joe’s return, another team member may rotate to yet another team – or it may make sense to wait a couple of months to allow the original team to absorb change. This is to learn from Joe and/or the visiting developer.

Many mangers will argue they are “special”. Since almost all are special, none are special. The only exception would be if the domain knowledge requirements are so deep, new talent just won’t fit in. This in itself, is a concern. For now, let’s switch to normal, pedestrian products.

Assume Joe is an “outstanding” performer and moves to product B. He will quickly see how well his skills and talents can be mapped to this new product. He surely will learn new processes and tools. The feedback opportunities for him are significant. Joe also can develop a new network of technical resources.

Both product teams get “new” people: developers with strong company experience and likely not timid about speaking up. They know the company culture, history & expectations; quite different from a new hire. These teams can get a critical review of their processes, tools and team culture. In fact, they may find out they cannot easily tolerate change! Question: how long does it take Joe to get productive – hours, days? Hint: it better be hours.

Joe’s manager gets to see the impact of the absence, albeit planned and controlled. Is the team well prepared for new talent? Are processes and techniques so specialized as to require years of experience in order to become proficient? Does the replacement find the code and architecture straightforward? Why isn’t the way we do business obvious to someone such as Joe?

HR can learn a great deal from this as well. Employee evaluations are supposed to consistent across teams; cultures somewhat similar; management execution consistent as well. Did I mention it there’s no reason not to run an experiment by rotating management team members as well? Now we’re really going to have fun!

The company gets stronger networks between its developers, quite possibly encouraging less turn-over. Product teams inherently grow stronger as weak links are exposed and eliminated. Special, irreplaceable personal are identified and their risk is reduced. Legal exposure can be reduced by determining inconsistent personal actions. Manager evaluations can be augmented by observing how well rotated talent experiments work out.

What’s not to like?

Driving Development Team Improvements

First Step Legacy Code Cleanup

“Legacy” probably means code written without a sense of craftsmanship, much less a code standard. It works, but the comprehension burden on the support team is high, as has been documented numerous times.

Many podcasts and articles mention that software development is still done today without source control. As bizarre as this seems, if this state still exists, then your worst legacy code nightmare is also present many times over! Here is a simple approach to start to move from the burden of “legacy” to something you can take pride in.

As you develop the new feature or bug fix, take note of the junk:

  1. Commented out code that is so old, that context is no longer understood.
  2. Constructors that don’t use initialization lists.
  3. Un-used variables.
  4. Unfortunately, many folks learned C as a first language. It used to require that variables be defined at the beginning of routines instead of close to usage.
  5. Methods or procedures that are hundreds of lines long.
  6. Extremely poorly named variables: my favorites are NP and MP, both of which point to new projects in a 300 line method.
  7. What about duplicated code? Are you looking out for that?
  8. Approximately 5,000 more sloppy practices…

This sort of junk greatly impedes comprehension. It can take hours to develop basic understanding, with low confidence! And for this, we’re paid big bucks.

So what to do:

  1. Assume ownership of the code. You are king and you rock!
  2. Fix to your hearts content, do not commit.
  3. Compare your work with the original.
  4. Commit your work, *except* for the feature/bug fix.
  5. While waiting on the review of this, re-implement the feature/fix and commit as a 2nd action.

Why two commits? The first gives the team confidence that the clean up is stable. It takes “extra” time, but the journey of 10,000 miles starts with a single step. Not only does this fix up a particular bit of code, the team probably also needs growth along these lines as well.

Just to belabor the point, a method was recently found to be of the form:

int max = 50;
for( int x = 0; x < max -50; x++ )
loop work...

Clearly a unit test would have found this. How many of us don’t have unit tests? Ahem. Be honest. It’s time to start somewhere!

PS. the PMD tool is great for tracking down duplicated code. Invaluable.

First Step Legacy Code Cleanup

Leadership vs Technical Debt

Several really good articles summarize the crushing consequences of technical debt. But where does it come from?

Martin Fowler’s blog posting “FlaccidScrum” notes:

“What’s happened is that they haven’t paid enough attention to the internal quality of their software. If you make that mistake you’ll soon find your productivity dragged down because it’s much harder to add new features than you’d like. You’ve taken on a crippling TechnicalDebt and your scrum has gone weak at the knees.”

It doesn’t matter if your process is waterfall, scrum, kanban or some other agile practice; technical debt is process-angst – it can simply crush your team & product.

At the Toronto Agile 2015 conference, Scott Ambler provided a very good presentation of the source of technical debt and mitigation strategies. His presentation & slides are available and very worthwhile.

Now consider an architect being offered a chance to bid on a bridge. The owner takes the bid and says: “Cut the price in half, bring the delivery in by 6 months and the contract is yours!” The architect says: “No thank you and walks off the job.” In the software business, how many folks simply sacrifice quality and accept the deal?

Leadership at all levels is necessary to address this. (Imagine if hospitals took on debt like this?) Team leads can implement the day-to-day processes and feedback mechanisms. Managers can review bug counts vs unit tests vs features for velocity. VP’s can determine how processes can be transferred across teams…

If there is a dearth of leadership and you still have little or no technical debt – you are in a very rare universe. Enjoy it while it lasts!

 

Leadership vs Technical Debt

Retrofitting Unit Tests Into Legacy Code

So what lessons can be learned from attempting to implement modern, safe, productive techniques into very old, monolithic, no-architecture software that has zero existing automated tests?

  1. It’s a lot harder than you think. Also, much more time consuming than possibly envisioned. And likely to not work.
  2. Example projects are simple and straightforward: as they should be. These all have the same baseline technologies. Legacy code has oodles of obsolete code/libraries & practices or techniques that hurt the logic part of your brain. The take-away is that this pain is a measure of the gap between good code and the target specimen.
  3. If the specimen doesn’t have a great architecture, unit testing will quickly expose this fault. And bring the unit test effort to a very quick halt. It’s not easy to retrofit an architecture into legacy code.
  4. Legacy projects may be Visual Studio projects that have been “upgraded” over the years. Compare the internal text/xml from one of these to a clean project. If you’re faced with building a unit test project with VS 20112 (1st MS VS release with CPP unit test framework) with VS 2008 projects, the comparison of the internals can be daunting. Consider scrapping the old project files and re-create new instead of upgrading; it will force you to think through your compiler & linker options. Maybe even understand them – nah, no time for that!
  5. Legacy code means many cooks have  been in the kitchen. Each genius has their own contribution create the “best” string class ever seen. You get the opportunity reconcile this tower of string Babble. You’ve heard it here; be prepared.

So then, what are your chances of success? Better define success on a limited scale, such as implementing a single unit test that can be executed with each build. This success vs cost will be very helpful towards future efforts.

Retrofitting Unit Tests Into Legacy Code