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.
- Code should be as self explanatory as possible.
- Misleading comments are more dangerous than no comments.
- Comments clutter code.
- Comments are the last thing people look at.
- If a programmer can’t express himself in a programming language, he is less likely to be able to express himself in a natural language.
3.
Sustainable spacing
3.1
Lines should not go beyond 80 characters.
- Reading narrow columns from top to bottom is comfortable, like the newspapers.
- Developer might write code using large monitors, but someone reading the code might use any kind of device.
- Important information might reside at the rightmost region of the line.
- Code reviewers might use tablet.
- Narrow lines is universally suitable for most devices.
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?