Revision as of 05:47, 19 July 2009
Despite the recent interest in functional programming languages a large part of today's software is object-oriented. Object-oriented software is composed of objects communicating via methods. So in a way it can be argued that not objects but methods are the basic building blocks of our software. While there is a lot of literature on design in the large, aka architecture/components and on a medium granularity (e.g., design patterns), surprisingly little can be found on designing single methods. This piece of advice claims that this design in the small matters a lot.
Key aspects in method design include clarity and readability. Ideally, any piece of source code should be readable like a good book: it should be interesting, clearly convey its intention and last but not least, fun to read. There are a number of very simple yet effective measures you can take towards this goal.
The most simple way to achieve readability is to use expressive names that properly describe the named concepts. In most cases this will mean relatively long names for methods and variables. Some argue that short names are easier and thus faster to type. First of all, modern IDEs can generate a variable name from the type of the variable in question - at least if you use a statically typed language. Even if you do spend time on typing longer names this usually has a pretty high ROI by saving you time later. Be even more careful in designing your method names because they are the verbs in the story you are trying to tell.
Another source of readability and comprehensibility is brevity. While it will not necessarily make your overall LoC count smaller carefully designing the size of your methods is beneficial as pointed out by Uncle Bobs contribution. As a rough guideline for an appropriate methods size I would argue for usually no more than 7+/-2 lines of code. This is motivated by applying the famous Rule of Seven which roughly states that the average human being can keep around 7 items in short term memory. In any case, make sure every method fits on your (and your coworker's) screen.
Keeping things simple (KISS) is a general rule of thumb in software design. One way of applying this to methods is to keep the cyclomatic complexity low – ideally under 4 or 5, definitely under 10. Cyclomatic complexity is a numeric value that can easily be computed by many tools and is roughly equivalent to the number of execution paths through a method. A high value of CC is empirically known to correlate with bugs and hinders unit testing.
It has been pointed out by many that mixing concerns is considered harmful. It stands to debate whether aspect-orientation is needed to avoid this but separation of concerns at the method level goes a long way to increase the readability and maintainability of your code. In a way this is a specialization of the Single Responsibility Principle (see Uncle Bob's contribution) which states that a class should have only one reason to change. Applied to methods this means that you should strive to map different aspects of your required behavior cleanly to different methods. This implies a finer level of granularity compared to designing at class granularity and is useful even if your class as a whole does not violate the SRP.
This idea of separation of technical and business, or generally, domain logic concerns is emphasized by the current popularity of domain-specific languages (DSLs). Within this approach the domain logic is expressed in a dedicated language specialized for the given domain which can ideally be edited by domain experts who are not programmers. DSL authors strive to make statements in the DSL sound just like 'plain English'. While this probably can help to improve communication with domain experts, careful design of short methods with low complexity which focus on a single fine-granular concern and proper expressive naming of methods and variables will certainly help to better convey the intention of your code to other developers - and to yourself. This will improve maintainability in the long run and, after all, most software development is maintenance. Happy method design!
(yes, this got a bit too long, I will try to make it shorter soon)