Documentation is code
development , php , annotations
Finally I found a new argument, after months and months, and it’s the documentation.
In my priority list there’s always an initial point: the documentation, if it’s missing then the library isn’t so good as it seems. Why? Simply because we aren’t in the mind of the developer that works on that library. I know you understand and watch for it too.
A question I always asked myself is: while a developer is working on a source code, is the documentation the first thing he writes? I must admit it, not for me, and the reasons are many: focus on the logic, times, deadlines, etc… and as always the documentation is the last thing to do, if I have time.
That’s really sad, because when I restart to code the day later I always forgot some things and I know that this is important, so while talking to other developers I always say “documentation is really important!” but when I look my code there’s always something that’s not described.
But today I think there’s a solution for this problem, if we consider the principle:
a good code should self-describe itself
of course we can’t always follow this principle, it should be used only in small pieces of code (mainly logic)!
To do this experiment I’ll use Symfony 2, because ehm… I love this framework ^^’.
Let’s start with models, if I write this piece of code:
there’s still nothing of what I’ll talk about but we already have a good description of our entity:
- we are talking about the table posts, that has four columns
- this table will be used to contain a set of Post objects
Not so much you think? Wait to work with a big database schema or a legacy project, then you’ll understand the importance of these few lines.
We can improve it very much, the first improvement we can do is the features we are missing:
As you can see we added some things to our post, things like a slug, a reference to the author, a password, etc… but some of you could still say “there’s no documentation”, and that’s not true, because we can see the nullable attribute in the PHPDoc and the attributes names, if the updated attribute can be nullable, than that attribute can be null and so still not updated (only created), the same thing for the password attribute, if it’s null than that post hasn’t a password.
Now the main question: who maintains all these attributes? Ok for the features, but this means that I have to write more code, I have DEADLINES. Here the documentation can help us!
Now everything that’s related to our post it’s not our problem, we can continue to focus on the post logic and have a more documented code, that’s what we wanted.
Honestly I don’t think this entity needs to be explained and the “Hello World!” level was already passed, we are building something really cool.
That’s not enough so we still have some works to do on our entity: validation, filtering, security, visibility and a thing we forgot initially, the database.
It’s not black magic, our code is documented just describing the entity, and that’s our code, because the annotations will be read to empower the entity. That’s the annotations’ power: we are reaching a documentation driven development.
Ops… forgot the database. Using doctrine 2 migrations we can auto-generate the SQL needed to migrate the database schema: docs.doctrine-project.org/projects/doctrine-migrations/en/latest/reference/generating_migrations.html
It’s a great tool, but I’m not here to talk about doctrine, the only thing I want say is: that tool will read your annotations! Yes, your documentation is already used.
In a common “MVC developer” this example should be already enough to start using annotations, but I’m not satisfied and I want talk about the Controller section. For this section I want try another approach:
It seems a well documented controller, while there are just few lines of code, there’s much more documentation, but what’s the problem? Now you have to configure the .htaccess, in the action logic there’s a control of the HTTP method (that’s not the logic, it’s a prerequisite), you have to throw and display an exception if the request is not GET (it’s still not the logic), you have to display the view (ok, it’s MVC, but it’s still not the logic), etc… it should be simple what is described at lines 22-23: retrieve the list of posts from the database and pass them to the view.
It’s well described, but it’s time lost too, because the time we used to describe the class, the method, the code, we could use it to write the code. This is a great example to explain what I mean, look this transformation.
You’ll immediately see that there are less lines of documentation, then why did I do this example? Because now there are only the lines we wanted, everything else shouldn’t be in the method code, because them are not in what the method was thought to do.
If you look these last two example you’ll see that everything in the first snippet documentation is in the second too: what does this method do? When it’s invoked? On which conditions it’s invoked?
These are only two examples of what we can do in the documentation, we can add breadcrumbs defining a hierarchy, describe the actions of a RESTful system, caching services, injecting dependencies, etc… everything just describing things, and after all these things generating an exportable documentation based on what we documented/described.
Documentation shouldn’t replace all the code, I’m against things like this or this, but documentation is no more a secondary thing to do in our list, it can be used to do the things in that list.
References
- https://github.com/schmittjoh/JMSSerializerBundle
- https://github.com/jbafford/PasswordStrengthBundle
- https://github.com/stof/StofDoctrineExtensionsBundle
- https://github.com/rdohms/dms-filter-bundle
- https://github.com/mmoreram/ControllerExtraBundle
- https://doctrine-orm.readthedocs.org/en/latest/reference/annotations-reference.html