Colour Your Environment

Have you ever been about to type a command and stopped to double-check if you’re on a test server or a production box? Or even executed a command and then had your heart stop because you weren’t sure which environment you’re logged in to?
One of the most effective ways to make sure you always know which environment you’re in is simply to colour-code. Use different coloured backgrounds on your desktops or change the colours of your menu bars.
When choosing colours I suggest the following:

  • Be consistent in your colouring. E.g. Production environments should always be the same colour. Never any other colour.
  • Use a simple colour scheme. Mark important differences rather than unimportant ones. For example, a 3 colour system: production, test and development environments.
  • Use a memorable colour scheme. For example, red for production to indicate “danger” or “stop”, because you need to be careful with production. Orange for “test” because you can be a little more relaxed but still need to be aware of other tests that are running. Green for your personal development environment, because you should be able to do anything on your own box.
  • Once you’ve picked a colour scheme, use it everywhere: paper folders, physical servers,  whiteboards, everywhere.

Hopefully, if you colour your environment, you’ll never have that “Production? Please don’t be production” feeling again.
 

Take Time to Go Fast

Imagine that you have to drive a long distance as fast as possible. Do you just jump in your car and put your foot down?

  • You won’t get there fast if you run out of fuel. You need to take time to fill up.
  • You won’t get there fast if you have an accident. You need to take time to drive safely.
  • You won’t ge there fast if you have to come back because you’ve forgotten something. You need to take time to pack properly.
  • You won’t get there fast if you pick a poor route. You need to take time to look at the map / program the SatNav.

We all know that, when driving, we need to take time to go fast.
Why don’t we understand the same thing about writing software?

Practice: Don't Repeat Yourself (DRY)

Description

To eliminate information repetition of all kinds.

Every piece of knowledge must have a single, unambiguous, authoritative representation within a system. Andrew Hunt and David Thomas (2000) The Pragmatic Programmer

This does not only apply to code:

  • Copy-paste (surface features of the code are the same)
  • Logical / Functional (the same logical process, but surface features vary)
  • Data (the same information in two different places)

But also to:

  • Documentation (requirements, for users etc.)
  • Software architecture
  • The software development process

To help you remember this practice, write out 100 times, “I will not repeat myself”.

Solutions

  • Repetition in process calls for automation
  • Repetition in logic calls for abstraction

Alternative Names

  • Single Source of Truth (SSOT)
  • Single Point of Truth (SPOT)

Forces Against

  • Ignorance of parts of the system (I didn’t know it was already there!)
  • Reliance on surface information rather then deep understanding. Assumption that is different because it looks different.
  • Reuse of existing information from several non-colsolidated sources.

Problem Overcome

  • Duplication requires that all copies must be maintained
  • Leads to larger code / data base, making finding defects more difficult

Contraindications

  • Automated derivation (eg. caches, generated code / documentation) where the original source is well know.
  • Certain optimisation techniques

Part of Development Lifecycle

  • All

Related Practices

  • YAGNI

Examples

  • Code reuse: Classes, subroutines, code libraries
  • Data Normalisation
  • Design Patterns

References

  • N/A

 

Some Comments on Comments

Code is communication, and comments can make a world of difference when it comes to making code clear and readable. Every seasoned developer has seen code that could have been made clearer with a few well-placed comments. At the same time, it isn’t unusual to find code that is littered with comments that are stale, unclear, unhelpful or just downright irritating.

Nothing can be quite so helpful as a well-placed comment Robert C Martin

Knowing when to comment and how to make a comment is an art, and one that clearly separates good programmers from poor ones. It is worth taking time, then, to review our practice in comment-writing. This is particularly true for those of us who have been around for a while. Coding practices and technologies have changed, and some of our old habits are inappropriate in modern programming environments.
The rest of this article outlines my current thinking on code comments, based on my research and experience as a programmer.

The Purpose of Comments

The purpose of comments is to help to make code readable.
For this reason, comments should be:

  • Terse
  • Readable
  • Helpful
  • Correct
  • Unambiguous
  • Maintainable
  • Placed as near as possible to the code that they’re commenting on

Unhelpful Comments

Comments that should be code

As far as possible, code should be self-describing. This implies that comments should explain why, because code already explains how.

Comments do not make up for bad code Robert C. Martin

  • Comments should not repeat what the code already says, for example:

  • Where possible, refactor code to eliminate comments
    • Better function / variable names can eliminate the need for comments
    • A simpler architecture or structure requires less commentary
    • Shorter methods eliminate the need for closing brace comments, like this:

    • Split functions / classes into smaller units to eliminate comments that act as section headers or division markers

Comments that should be part of source control

…and if you aren’t using source control then you already have a bigger problem than bad comments!

  • Attributions (developer’s names)
  • Code version numbers
  • Journal comments (who did what and when)
  • Commented-out code
  • History of changes, like this:

Misleading comments

One of the biggest problems with comments is that they rot over time. The comment you write today may not match the code you write tomorrow.

  • Ambiguous or unclear statements
  • Outdated information
  • Comments that don’t apply to the present context
  • Information that applies only to specific cases
  • Comments that are just plain wrong

Comments that create unnecessary work for the author / maintainer

If comments take up too much time to maintain then they are less likely to be maintained.

  • Non-trivial formatting. Insisting, for example, that all comments are in neat boxes made of asterisks
  • Mandated comments – that your boss / process / toolset tells you should be there but which add no real value, for example:

  • Markup in comments (except when it is required by tools that generate documentation)

Comments that create unneccesary work fort the reader

  • Noisy comments
    • Comments that contain much information / irrelevant information
    • Chatty comments. Blah, blah, blah.
  • Poor spelling / punctuation in comments
  • Non-local information (such as information how callers will use a value returned from a function – that’s the caller’s business)

Unprofessional comments

  • Anything offensive, derogatory or insulting
  • Jokes / cultural references should be included sparingly, sensitively and kept short and/or clearly delimited as such

The practice of inserting jokes or cultural references in comments is a matter of some debate. Some people think they are invariably unprofessional, as they convey a lack of seriousness and waste time for both their authors and readers. Others (myself included) feel that they are conducive to a good working atmosphere. However, they should be easy to skip over for readers of the code, and should never risk your professional reputation nor that of your employer/customer.

Beneficial Comments

File headers

  • Copyright and other legal notices (everything else can be omitted)

Explanations and clarification

  • When you can’t explain something in code (by using a function name, for example)
  • Explanation of the intent of code
  • Clarifying the reason for a decison
  • Clarification of code you can’t alter, like library call results

To draw attention

  • Warnings of consequences
  • Drawing attention to important things that appear inconsequential

Comments parsed by development tools

  • TODOs
  • Documentation markup

Comments that save the reader time

Some of this last set may be a little controversial, but I find them beneficial:

  • Brief explanations of concepts, algorithms etc. so save the reader referring to external documentation
  • Comments that help interpret the solution in terms of the problem domain
  • Comments that signpost external documentation (such as urls)

Further Reading

  • “Clean Code” by Robert C. Martin

Best Practices: Why aren't they followed?

We all know it is a good idea to follow best practices, but we also know that we don’t always follow it. I find that interesting.
Now, when I want to change something, I find it helpful to understand why things are the way they are. It is worth asking, then, why don’t we follow best practice? And what can I do about it?

Ignorance

Simply not knowing what constitutes best practice appears to be a reasonable excuse for not following best practice. For someone new to the discipline, this is fair. But what about those of us who have been in the profession for some time? Is it enough to argue that nobody has shown us the way? That nobody has made the information we need available to us? Well, I do sympathize with people who face these issues. But only to some extent.
The truth is, my career is my responsibility. I have a professional responsibility to develop our skills in our chosen craft, and we live in an age where this information is more readily available than it might have been in the past. I can choose to learn if I want to.

Pressure to Deliver

My client needs a solution delivered yesterday, and my family needs me at home in the evening. When am I supposed to learn, let alone implement, best practices?
Actually, the problem for the company is not lack of time. It is lack of understanding. The reason I say this is that best practices, by definition, deliver more value for less cost. If they didn’t, they wouldn’t be best practices. The way to deal with this, issue, then, is to find ways to communicate the benefits of best practice to the people around us – having firmly established what best practice actually is as it applies to our situation. We need to persuade managers that a small investment now – a delayed delivery – will reap long-term benefits.

Take time to go fast.

Part of the solution is to recognize  that developing my skills isn’t my responsibility alone. My employer has a responsibility to support my personal development – to give me time and resource to grow so that I can add more value to the company. Sometimes, however, organizational leaders need to be reminded of this. I may have to persuade my managers that allowing me resource to grow will benefit them in the long term.

Other Developers

I am led to believe that, sometimes, other professionals actually foster ignorance of best practice. They may feel threatened by having to learn new skills or by their own practice being challenged. They may feel that they already know best, that their methods are tried and tested. They may have worked hard to develop their own practice, and as a result have formed a strong emotional attachment to the way things are done at the moment. I imagine that it takes strong leadership skills to overcome such challenges. If you face this problem (and you’re sure that the practices you propose actually are the best ones) you may want to take a course in influencing people along with your studies in professional practice. As for me, I’m fortunate that I work with like-minded people. Assuming my colleagues don’t think that I’m one of those…

Conclusion

First, I see that there are two directions from which my behavior is influenced:

  • From within – by my own assumptions and feelings and understanding
  • By my external environment – the systems and relationships that surround me

I recognize that I need to deal with both of these areas.
Second,  it seems that professional quality is not a technical problem but a people problem. To develop it, I need to develop myself and my relationships with the people around me. Which is interesting in itself. The reason I got into technology because I didn’t really see myself as a people-person. It seems I was mistaken: I’m do a technical job, so I must be a people-person after all.

Naming Things

Naming Matters

For programmers, naming is an important activity:

  • It has a significant impact on code readability
  • We do it a lot

General Principles

  • Don’t make me think
  • Make wrong things look wrong
  • Take time to go fast

General Guidelines

  • Don’t be a perfectionist – don’t let naming paralize you
  • If you can improve it, do so
  • Remove the comment and improve the name
  • The wider the scope the longer the name

Follow Standards

  • Follow platform conventions
  • Call things the same as they are usually called
  • Use programmer speak for programmer things (solution domain)
  • Use the customer’s language to describe the customer’s things (problem domain)
  • Spell consistently and correctly
  • Pick one word to describe a concept and stick to it
  • Don’t inventing language where you don’t need to

Encourage Communication

  • Use pronouncable names
  • Invent language where you need to
  • Don’t be cute, clever or funny: not everyone will get it
  • Avoid cultural references

Be Useful

  • Avoid disinformation
  • Avoid noise words – words that don’t add anything (a, the etc.)
  • Avoid redundancy
  • Use searchable names
  • Think sortability – this will depend on the IDE
  • Avoid hungarian – it doesn’t usually add anything
  • Add context where it helps, remove it where it doesn’t

Specific Scenarios

  • Class names: noun-phrases, not a verbs
  • Method names: verb-phrases, not nouns

Further Reading

When Improving Technology Makes Things Worse

A Secret

We all know that bad technology is bad for business. By “bad” I mean technology that doesn’t do what it is supposed to do, or which does it wrong, or which costs more to implement than the benefits it brings.
But I’ll let you in to a secret:

Good technology is sometimes bad for business.

Now, I develop software for a living, so I shouldn’t really be telling you that. I should be saying that good technology is a good thing – especially software – and that it will increase your bottom line, make you more productive, make you happier and generally improve your life.
And each of these things is true… but only some of the time.

The Problem

The problem is this:

  • Good technology makes processes more efficient.

At first sight, this sounds like a good thing. To understand why it often isn’t so good, consider two effects that technology will have on an organisation:

Efficiency and Effectiveness

According to Jim Collins (in Good to Great), “great” organizations all employ technologies that enhance their competitiveness. Collins also confirms the role that technology can play if you don’t keep up. However, he explains that technologies are accelerators that amplify the company’s strengths and weaknesses. This means that a company that aims to improve processes by adding technology will magnify both the good and the bad aspects of those processes. In any business area where practices are less than perfect, the imperfections will be amplified by technology. The problem is that making processes more efficient doesn’t necessarily make them more effective.

Lock-In

The other effect of introducing technology is that it can be a hindrance to change. A new software system, for example, can be a very costly acquisition (especially given that companies often underestimate the cost of software). Once the software is deployed, however, processes become locked-in to the way the software operates. Changes to processes often require changes to the software – which can be prohibitively expensive. The result is that the company looses agility, becoming bound to outdated practices that they know are broken, that they want to change, but which are impossible to shed because of technical constraints.

An example of this is the clocking system that was used at a company where I did some work. It was based on decimal hours rather than hours and minutes, so 7 hours and 30 minutes appeared on screen as 7.5. Everyone knew that this was a bad idea, because the entire staff of the company wasted time every month converting their clockings from hours and minutes into decimal hours. However, this method of working was locked in by the technology. When a companion time-sheet system was introduced, the specification indicated that it should also work in decimal hours so it would be compatible with the first system, further locking-in wasteful behaviour.

Conclusions

So, does all this make all technology a bad thing? Not at all. But it does suggest that we approach technology in a different way:

  • Great companies value technology.
  • Technology should not bee seen as a panacea, but a method of amplifying existing practices.
    • Business needs should drive technology, not the other way around.
    • Business systems should be fixed before introducing technology to make them more efficient.
  • Technology should be chosen on the basis of how easy it is to change as well as on how well it meets current needs. For example:
    • Choose an Agile approach to bespoke software development.
    • Reduce dependencies between technologies.

How to Improve Service and Lower Costs

Focus on the systems that provide value

How you view a problem is the key to the way you solve it. If our focus is on anything but the systems that provide value we will be driving waste into our business.

Don’t focus on economies of scale

Standardisation isn’t always improvement

Don’t focus on tools, but on principles

Every situation is different.
At a high level, the ways that a service organisation provides value are different from a manufacturing business or an R&D department. This is why lean tools don’t translate to service organisations.
At a low level, each organisation has a different pattern of demand for its services. This leads to different problems which require different types of solutions.

Don’t focus on individual processes

Efficient processes don’t always lead to efficient systems.
Consider the value stream. Costs arise from end-to-end services, not individual transactions. Lowering individual transaction costs can increase overall transaction costs.
However, poor performance in one area has a knock-on effect in other areas.

Focus on providing better end-to-end services

  • Better service lowers costs
  • Follow the value flow, eliminate waste
  • Fragmentation of flow introduces waste (e.g. separating back-end from front-end breaks up flow)
  • Improve systems  – systems control behaviour

Create better measures

  • High scores don’t add value
  • Measures should relate to the purpose of the system from a customer POV

 

Best Practice: Foundations

When I became a full-time developer, I determined to be the best developer I can be. I set out to learn what best-practice means in my chosen profession, and then to learn to apply it to my practice. Thus far, it has been an interesting and largely enjoyable journey.

Of course, I’ve made some fundamental mistakes. One reason for this is that different developer’s ideas of what best-practice actually means is often quite different. Another is that best-practice is often assumed applied on a one-size-fits-all basis.

One way through this morass is to understand the principles on which best-practice is founded. One of those principles is that best practice must be determined by your overall purpose. Today, I came across an article by Eric Lippert that sums up our purpose as well as anything I’ve come across up to this point:

The purpose of code is to create value by solving a business problem. Eric Lippert

Best practice, then, is that which most effectively enables us to add business value. However, different software projects add value to the business in different ways. For example, a one-off data conversion is very different from an OLTP application, which is in turn very different from an overnight batch job. For this reason, best-practice will vary between different projects.
Going a little deeper, Lippert identifies 3 areas in which code displays fitness for purpose:

  1. Good code is code which “works correctly according to its specification to actually solve the stated problem”
  2. Good code “communicates its meaning to the reader who needs to understand its operation”
  3. Good code “allows for relatively low-cost modification to solve new problems as the business environment changes”

The relative importance of these 3 areas can vary between projects. A quick throw-away data conversion script needs to be functional, but less emphasis can be placed on modification and readability. On the other hand, an application like Microsoft Word will be worked on by many developers and maintained through numerous development cycles. As such, readability and maintainability need to be emphasised more than providing every possible bell and whistle that would benefit a very small minority of your customers.
In summary, then, best practice is any practice that adds business value by balancing requirements for functionality, maintainability and adaptability. Knowing this, we can evaluate the applicability of any so-called “best” practice in the context of our own situation,

Best Practices: Variables

Notes from Code Complete 2: Chapter 10

Date Types

  • Know your data types (10.1)

Declaration and Naming

  • Declare all variables (turn off implicit declarations) (10.2)
  • Follow naming conventions (10.2)

Initialization

  • Initialize each variable as it’s declared (10.3)
  • Declare and define each variable close to where it’s first used (10.3)
  • Initialize working memory at the beginning of your program
  • Use the compiler setting that automatically initializes all variables
  • Initialize a class’s member data in its constructor
  • Pay special attention to counters and accumulators – ensure that they are initialized properly and, if necessary, reinitialized each time they are used
  • Check the need for reinitialization
  • Check that variables are reinitialized properly in code that’s executed repeatedly
  • Initialize named constants once; initialize variables with executable code
  • Check input parameters for validity
  • Use a memory-access checker to check for bad pointers
  • Don’t assign a value to a variable until just before the value is used
  • Use final or const when possible
  • Use named constants (avoid magic numbers)
  • Strike a conscious balance between the flexibility of late binding and the increased complexity associated with late binding

Scope

  • Ensure that variables have the smallest scope possible
  • Develop the habit of declaring and initializing all data right before it’s used
  • Localize References to Variables
  • Keep Variables “Live” for as Short a Time as Possible
  • Initialize variables used in a loop immediately before the loop rather than back at the beginning of the routine containing the loop
  • Group related statements
  • Break groups of related statements into separate routines
  • Begin with most restricted visibility, and expand the variable’s scope only if necessary

Purpose

  • Use each variable for one purpose only
  • Avoid variables with hidden meanings
  • Make sure that all declared variables are used

Persistence

  • Write code that assumes data isn’t persistent (10.5)

Release

  • Set variables to “unreasonable values” when you’re through with them (10.6)

General

  • Enable and pay attention to compiler warnings