Seven ineffective coding habits of many programmers | Kevlin Henney

Sep 16, 2017

Here are the seven habits talked about by Kevlin Henney at Istanbul Tech Talks 2016.

1.

How much of the code is actually communicating and how much is noise? Reduce code size and remove stuffs that doesn’t add value.

2.

Comments often make code noisy.

3.

Sustainable spacing

3.1

Lines should not go beyond 80 characters.

3.2

Code should visually convey information. When things are aligned, people assume somehow they are related. So similar stuffs should be aligned.

Positioning argument list

How not to:

public int howNotToLayoutAMethodHeader(int firstArgument,
    String secondArgument)

How to: Group arguments together, better readability

public int howToLayoutAMethodHeader(
    int firstArgument,
    String secondArgument
)

Don’t do this:

public int doNotDoThis(int firstArgument,
                    String secondArgument);

Because this is unstable, alignment breaks when refactored.

public int unstable(int firstArgument,
                    String secondArgument);

These are not prone to breaking alignment when refactored.

int thisIs =
    stable(
        someArgumentOrExpression,
        anotherArgumentOrExpression);

int andThisIs = stable(
    someArgumentOrExpression,
    anotherArgumentOrExpression);

Positioning curly braces

Don’t do this: Visually unclear where the body of a block starts.

public ResultType arbitraryMethodName(
    FirstArgumentType firstArgument,
    SecondArgumentType secondArgument,
    ThirdArgumentType thirdArgument) {
    LocalVariableType localVariable =
        method(firstArgument, secondArgument);
    if(localVariable.isSomething(
        thirdArgument, SOME_CONSTANT)) {
        doSomething(localVariable);
    }
    return localVariable.getSomething();
}

Do this:

public ResultType arbitraryMethodName(
    FirstArgumentType firstArgument,
    SecondArgumentType secondArgument,
    ThirdArgumentType thirdArgument)
{
    LocalVariableType localVariable =
        method(firstArgument, secondArgument);
    if(localVariable.isSomething(
        thirdArgument, SOME_CONSTANT))
    {
        doSomething(localVariable);
    }
    return localVariable.getSomething();
}

Or this:

public ResultType arbitraryMethodName(
        FirstArgumentType firstArgument,
        SecondArgumentType secondArgument,
        ThirdArgumentType thirdArgument) {
    LocalVariableType localVariable =
        method(firstArgument, secondArgument);
    if(localVariable.isSomething(
            thirdArgument, SOME_CONSTANT)) {
        doSomething(localVariable);
    }
    return localVariable.getSomething();
}

4.

Naming should be simple, small, precise

4.1

Reduce names with redundant information. Stop trying to dance around the name, just say the name.
Don’t:

public interface ConditionChecker
{
    boolean checkCondition();
}

Do:

public interface Condition
{
    boolean isTrue();
}

4.2

Meaningless words: Object, Thing, Component, Part, Manager, Entity, Item. How much of a name is left when you remove all of these words?
Example: Putting the word Exception behind every exception is bad. Because it is obvious that something that comes after a throws statement is obviously an exception. Exceptions that indicate something bad happening doesn’t require the word exception in the end.
AccessViolationException \(\rightarrow\) AccessViolation
IndexOutOfRangeException \(\rightarrow\) IndexOutOfRange
InvalidOperationException \(\rightarrow\) InvalidOperation

4.3

Name exceptions using the problem so that it becomes obvious even without the word Exception.
ArgumentException \(\rightarrow\) InvalidArgument

5.

Missing abstraction: Code in the language of the domain.
Don’t:

if(portfolioIdsByTraderId.get(trader.getId())
    .containsKey(portfolio.getId()))
{
    ...
}

Do:

if(trader.canView(portfolio))
{
    ...
}

6.

Don’t provide setters if only getters are needed. Getters don’t necessarily need the word “get” because sometimes its redundant.

public class Money implements ...
{
    ...
    public int getUnits() ...
    public Currency getCurrency() ...
}

Better:

public class Money implements ...
{
    ...
    public int units() ...
    public Currency currency() ...
}

Getting something is an imperative statement in English which means having some kind of side effect.

7.

The most important word in TDD is “driven”. Are tests driving the development?