A blank jigsaw puzzle with one missing piece in the middle

The signature of a function, or method, is its name together with the signature of its inputs and outputs.

To get the benefits from abstractions we need to turn each signature into a curiosity barrier. When looking at the signature, a developer should know what the piece of code does, without needing to read the implementation. To achieve that we use all the parts of the signature.

Name

Naming is hard, but rewarding if done right. Naming as a process can help, since it uses an iterative approach to finding a really good name. Making sure that the domain is present in the naming is also key. In a presentation on documentation Cyrille Martraire suggest creating a word cloud, a weighted visual representation, from the codebase. If you can not see your domain in the cloud that is a code smell.

Inputs

Make sure that the prerequisites for the code is explicit. You want your code to be a small friendly blob, that can be moved around. You do not want it to be something that looks small and cute, but where the backside have tentacles that are everywhere and where moving it will kill everything that it worked its way into. Achieving this is done by having all collaborators as inputs. This is often called dependency injection. Ways to access system time, or other environment information, is also a collaborator. Writing unit tests is a good way to discover what your code needs access to. The setup for the test should only consist of constructing inputs for the call. If the list of inputs is too big, that is a sign that the code needs refactoring.

Outputs

Side effects are dangerous, so having outputs that tell the whole story of what has been done is preferable. If the purpose of the code is a side effect, like sending an email or saving to the database, it is good if the output reflects that. One way is to let all functions with side effects be void functions. That requires that dealing with errors is done by some other means, so it is not always possible. For side effect free functions, the output should give as much information on what to expect from the function as needed. The unit tests for non-void functions should be fine only asserting on the output (for the happy path at least), since they should be side effect free.

The goal is to use all the parts of the signature to still the curiosity of the developer using the code. Our struggle to achieve that will also tell us things about the design, if we listen. So make sure to use all the parts of the signature when describing what your code does.

Related texts

A single frosted leaf with clear contours and veins.

TDD in the context of writing code to be read

Wunder Baum hanging from a car window (Known as Little Trees in most English-speaking countries)

Wunderbaum testing