
I’m not saying verbose should be a dirty word, just that it does have a pejorative meaning. If you’ve used *nix command line tools often enough, you’ll know that -v is often used as a flag for “verbose”. This usually ends up in some useful information coming out of the log or stdout. -vvv usually means “very verbose” and too much information pours out to be of any use. And this is the risk:
If verbose is your end-goal, then the more verbose you are, the better.
Right? I mean that makes sense. If “quality” is your end-goal, then more and more quality is a thing to strive for. Same goes for “agile”, “fair”, “loyal”, “just”. All these words suggest that the more you pile it on, the better. This is not true of verbose. Keep getting verbose, and in fact, you just get more noise.
I’m probably nitpicking this to death, but I’m only doing so, now, because I think I have a better quality to strive for:
Really in our code, we wan’t to be more expressive. We want every line we read to convey it’s meaning.
If you check out expressive at dictionary.com there’s also a nice set of synonyms:
Synonyms: These adjectives mean effectively conveying a feeling, idea, or mood: an expressive gesture; an eloquent speech; a meaningful look; a significant smile.
I think eloquent is a good word too, it usually conveys meaning in a terse manner. That’s right, less verbose, just enough meaning and no more.
This code is readable, but not expressive:
public class EmployeeModel {
....
public function save():void {
if ((editingEmployee.name.length > 0) && (employees.checkUnique(editingEmployee.ssid))) {
employees.comit(editingEmployee);
}
}
...
}
So now I refactor it.
public class EmployeeModel {
....
protected function employeeIsValid(employee:EmployeeVO):Boolean {
return ((employee.name.length > 0) && employees.checkUnique(employee.ssid))
}
public function save():void {
if (!employeeIsValid(editingEmployee)
return;
employees.comit(editingEmployee);
}
...
}
I use a guard clause for starters because they convey intent more clearly.
Then I extract the method (all praise ctrl-alt-m in IntelliJ IDEA) employeeIsValid(). This gives the guard more meaning, and also gives the extracted condition more meaning. It’s a win-win.
Now, is this the following code more expressive or more verbose?
public class EmployeeModel {
....
protected function employeeNameIsValid(employee:EmployeeVO):Boolean {
return employee.name.length > 0;
}
protected function employeeIsValid(employee:EmployeeVO):Boolean {
return (employeeNameIsValid(employee) && employees.checkUnique(employee.ssid))
}
public function save():void {
if (!employeeIsValid(editingEmployee)
return;
employees.comit(editingEmployee);
}
...
}
I extract the name comparison (pretend for a moment that it couldn’t be done in the VO) - employeeNameIsValid().
This is not too bad, I think. It expresses that an employeeName that’s greater than 0 chars long is valid.
However this is easily inferred from the previous example, because the test is inside ‘employeeIsValid’ - It would read just as well, and so I wouldn’t bother with this extra step. At least, not until it got more complex. Remember, most refactorings are bidirectional.
In our complex lives, rules and guidelines help us avoid rethinking everything that crosses our paths. Rules are the outcomes of pattern recognition.
We recognise repeating or similar stimulus in the world, and our ‘understanding’ of these stimuli is a “rule”.
I’m not quoting anyone here, and I may be oversimplifying the case, but I think this is a reasonable statement. Recognise: Drop a ball, it falls to the ground. The rule: releasing a ball causes it to fall toward the ground.
As programmers, there are a lot of rules to follow. Thankfully. Otherwise every line of code would be the realisation of hours of complex reassessment of stimuli (variables, requirements, other code..)
However when you discover, or are given, a rule to follow, it may not be “useful”. Hopefully at your disposal, you have the reasoning for the rule, but that can still leave you with more questions than answers. I’m talking about best practices here. If you want people to follow rules, you had better make it easy for them to identify wether they are applying the rules consistently.
In Clean Code, Uncle Bob wrote:
The following advice has appeared in one form or another for 30 years or more. FUNCTIONS SHOULD DO ONE THING. THEY SHOULD DO IT WELL. THEY SHOULD DO IT ONLY.
There are a lot of reasons to follow this rule. The first one that comes to mind:
Any unit of code that does only one thing is easier to comprehend when revisiting it in the future.
That’s good enough reason for me, but the rule still isn’t useful. And with a great deal of consideration to his readers, Uncle Bob continues with the “useful” part.
(Or, how to apply the rule.)
TO RenderPageWithSetupsAndTeardowns, we check to see whether the page is a test page and if so, we include the setups and teardowns. In either case we render the page in HTML.
If a function does only those steps that are one level below the stated name of the function, then the function is doing one thing.
This is so awesome. The ‘TO’, he advises us, is from LOGO, and is simply the syntax to introduce a method in that language. But I see this as a clue.
Clues remind us how to check if a rule is properly applied. Clues direct us into the mode of thought that originally recognised the pattern to which the rule applies. Perhaps clue’s are unit tests for rules.
Dan North, in his BDD article uses clues to remind us how to establish a good “User Story” and “Acceptance Criteria”. In fact his clues are so good that I quickly forget the rules and reasoning for user stories and acceptance criteria, and just find myself enjoying the use of the clues.
Writing a user story is a breeze now. I write down:
As a
I want
So that
I spend very little time now thinking about the complexity of my user story, instead I’m compelled to keep it simple and provide the three most important bits of information:
Who wants it,
What do they want,
To what end?
Why did I mention any of this? Because I assume people who bother to read our blog are either looking for inspiration to improve their own code, or want to help mentor others.
For the inspiration-seeking, look for people who give you more than rules and reasoning, but also give you mechanisms to ease the application of them.
For the educator, provide clues, help others find it easy to apply your rules. The rules should make their life easier, but they’re not enough on their own.
© 2010 - VisFleet Ltd
No prawns were harmed in
the making of this website
Comments