Methods Matter

From WikiContent

(Difference between revisions)
Jump to: navigation, search
Current revision (08:33, 18 August 2009) (edit) (undo)
 
(6 intermediate revisions not shown.)
Line 1: Line 1:
-
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.
+
A large part of today's software is written using object-oriented languages. 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 code. While there is a lot of literature on design in the large — architecture and components — and on medium granularity — e.g., design patterns — surprisingly little can be found on designing individual methods. Design in the small, however, matters. A lot.
-
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.
+
Ideally, any piece of source code should be readable like a good book: it should be interesting; it should convey its intention clearly; and last, but not least, it should be fun to read.
-
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.
+
The simplest way to achieve readability is to use expressive names that properly describe the concepts they identify. 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. Modern IDEs and editors are capable of simplifying the typing, renaming, and searching of names to make this objection less relevant. Instead of thinking about the typing overhead today, think about the time saved tomorrow when you and others have to reread the code. Be particularly careful when designing your method names because they are the verbs in the story you are trying to tell.
-
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 it simple (KISS) is a general rule of thumb in software design. One source of simplicity is brevity: Most of the time, shorter methods are simpler than long ones. While a low line count is a good starting point, the overall cognitive load can be further reduced by keeping the cyclomatic complexity low — ideally under 3 or 4, 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 cyclomatic complexity complicates unit testing and has been empirically shown to correlate with bugs.
-
+
-
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.
+
Mixing concerns is often considered harmful. This is normally applied to classes as a whole, but applied at the method level it can further increase the readability of your code. Applied to methods this means that you should strive to map different aspects of your required behavior cleanly to different methods. Such a separation of technical and business concerns facilitates, and benefits from, the use of a well-defined domain vocabulary. Using such a vocabulary helps to reveal intention in your methods. This can ensure that a consistent and ubiquitous vocabulary is used when speaking to domain experts, but it also ensures that methods are focused and consistent, so that developers also benefit.
-
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'.
+
When you have properly separated concerns try to do the same with levels of abstraction. This is achieved by staying at a single level of abstraction within each method. This way you don't jump back and forth between little technical details and the grander motives of your code narrative. The resulting methods will be easier to grasp and more pleasant to read.
-
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)
+
All in all, careful design of short methods with low complexity that focus on a single fine-grained concern and stay at a single level of abstraction combined with proper expressive naming will definitely 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!
 +
 
 +
 
 +
 
 +
By [[Matthias Merdes]]
 +
 
 +
This work is licensed under a [http://creativecommons.org/licenses/by/3.0/us/ Creative Commons Attribution 3]
 +
 
 +
 
 +
 
 +
 
 +
Back to [[97 Things Every Programmer Should Know]] home page

Current revision

A large part of today's software is written using object-oriented languages. 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 code. While there is a lot of literature on design in the large — architecture and components — and on medium granularity — e.g., design patterns — surprisingly little can be found on designing individual methods. Design in the small, however, matters. A lot.

Ideally, any piece of source code should be readable like a good book: it should be interesting; it should convey its intention clearly; and last, but not least, it should be fun to read.

The simplest way to achieve readability is to use expressive names that properly describe the concepts they identify. 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. Modern IDEs and editors are capable of simplifying the typing, renaming, and searching of names to make this objection less relevant. Instead of thinking about the typing overhead today, think about the time saved tomorrow when you and others have to reread the code. Be particularly careful when designing your method names because they are the verbs in the story you are trying to tell.

Keeping it simple (KISS) is a general rule of thumb in software design. One source of simplicity is brevity: Most of the time, shorter methods are simpler than long ones. While a low line count is a good starting point, the overall cognitive load can be further reduced by keeping the cyclomatic complexity low — ideally under 3 or 4, 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 cyclomatic complexity complicates unit testing and has been empirically shown to correlate with bugs.

Mixing concerns is often considered harmful. This is normally applied to classes as a whole, but applied at the method level it can further increase the readability of your code. Applied to methods this means that you should strive to map different aspects of your required behavior cleanly to different methods. Such a separation of technical and business concerns facilitates, and benefits from, the use of a well-defined domain vocabulary. Using such a vocabulary helps to reveal intention in your methods. This can ensure that a consistent and ubiquitous vocabulary is used when speaking to domain experts, but it also ensures that methods are focused and consistent, so that developers also benefit.

When you have properly separated concerns try to do the same with levels of abstraction. This is achieved by staying at a single level of abstraction within each method. This way you don't jump back and forth between little technical details and the grander motives of your code narrative. The resulting methods will be easier to grasp and more pleasant to read.

All in all, careful design of short methods with low complexity that focus on a single fine-grained concern and stay at a single level of abstraction combined with proper expressive naming will definitely 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!


By Matthias Merdes

This work is licensed under a Creative Commons Attribution 3



Back to 97 Things Every Programmer Should Know home page

Personal tools