dimanche 6 décembre 2020
Faut-il commenter son code?
jeudi 5 novembre 2020
Continuous Delivery : What about a database change?
Yesterday I ran a Continuous Deployment workshop in production, namely Continuous Deployment of a
database change. Sounds advanced?
Actually it's easy, just counter intuitive...
![]() |
It can be really scary to roll out this big feature because it includes a database change. But by splitting it into 3 to 5 chunks it's a lot less scary and can be done with sometimes shorter downtime. Here are the chunks:
1st deploy: Add the column/table to the database
2nd deploy: fill the new column with values. Check
3rd deploy: Rerun migration script while app is down. New code writing to the new column (but not reading).
4th deploy: New code or feature flip, to only use the new column both for reads and writes
5th deploy: remove old column and old code. (Possibly days later)
dimanche 4 octobre 2020
Less error handling noice in GO: CombineErrors
TDLR; A nice trick to greatly reduce error handling in Go code.
Error handling in go can easily get in the way of readability in Go. Big time! Reducing the verbosity of error handling and in particular the amount of if-statements that invade our application code has been occupying my thoughts for a few months now. I’m appalled that it’s so difficult to find good tricks on this. The go blog has very little information on this. Let's face it I risk GOing nuts!
Some time ago I realised that some errors don’t have to be handled immediately. Postponing error handling opens up a few possibilities. The first and foremost is CombiningErrors. But let’s first look at the problem. Here’s a bit of typical code for obtaining data from somewhere.
Now that’s a short example but imagine this constructor taking a few more arguments.
In this case we’re producing 3 errors. What if we could just combine those three into a single error, that will be nil if all sub-errors are nil, then we could return only one function. Something like
This combining function seems like generic code so there’s probably a library out there doing the job. Indeed there is, for instance https://godoc.org/go.uber.org/multierr and https://godoc.org/github.com/hashicorp/go-multierror
Now there’s just one small improvement to do here, one that I actually learnt from one of the posts at the go blog. There’s no need to check for a combined error with an extra if-statement. We can just return the globalErr, it'll be nil if all sub-errors are nil, and the calling function will test for errors either way.
Much better :)
Now this is a trick that won't apply in every case. Actually when does it apply? Well I'd argue that this can be used whenever there is no damage done by pursuing execution after a first error. Which in my team's code is quite often. Nice :)
Next time let’s look at another trick where we’ll transform a sequence of error generating statements into a list of functions. Let’s see how that helps.
mercredi 17 juin 2020
Recorded refactoring of the Untangled Conditionals kata
It's always an immense pleasure to remove conditional logic in code, I hope you'll find it fun too!
The big question is how simple can it get? Guess you'll have to watch it ;)
Also check out the kata untangled-conditionals-kata. It has the author's, Tom Oram, video of solving it in a different manner in a different language. It's great stuff.
mercredi 12 février 2020
Formation en ligne : proposer une pédagogie adaptée
L’humain et l’interaction personnalisée au coeur de la formation en ligne
mardi 28 janvier 2020
Quand faut-il refactorer pour éviter le legacy?
Quand est-ce que nous devons refactorer le code? Pour ne pas contracter trop de legacy il faut refactorer, on le sait, mais quand?
Est-ce qu'il faut faire des stories de refactoring? Est-ce que ce sont des stories "utilisateur"? Ou faut-il le faire plutôt au fil de l'eau? Pour moi la réponse est "majoritairement au fil de l'eau", pendant les stories. Dans cette video on voit pourquoi cette approche est la plus intéressant à mon sens et s'il faut le faire avant, pendant ou après la story.
On verra aussi en quoi ceci peut être contre nature au début car c'est pas dans nos habitudes.
Toi aussi tu aimes le code propre et le legacy t'embête, voire le fais chier :), viens à mon webinar sur la dette technique, ce vendredi 31/1 et tu pourras poser les questions qui te brulent en direct!
T peux aussi jeter un oeuil sur la formation interactive en ligne Clean code, sortir de la dette technique, il y a des chances que ça te plaira autant que les personnes qui l'ont déjà suivi ;o)
lundi 6 janvier 2020
Stop feeding the big classes - Class division
I wouldn't even try
I do admit that it is very hard to write unit tests for these classes. I would find it very difficult to write good unit tests for them too. In fact I wouldn't even try to test this with unit tests. Now what I would do is I would extract the behaviour that I want to modify into other classes or more likely to a completely new class. If I move out a method of say 10 to 50 lines of code then that's very easy to test and things that are easy to test are easy to change by adding behaviour to it. In doing this, besides making things testable, we improve things by splitting things into smaller pieces. Smaller pieces are more easy to understand to test and to assemble into new behaviour i.e. reuse these classes elsewhere.![]() |
| flickr.com/photos/102642344@N02/10203178726/ |
Given that we do split the big classes into pieces as we do features then it doesn't take many stories to make our codebase a lot more maintainable and all the way we been able to work with lower level tests. All we needed to ensure is that the things we split apart are meaningful pieces that are functionally coherent. This is probably the most difficult part - extracting something meaningful. It requires being able to design code and if we don't have much practice doing it won't be very good. On the other hand if we don't start practicing this then all code we create will just be a bigger and bigger mess. I mean there's a reason (almost) all living things grow by cell division, not by cell growth.
The actual act of extracting something is really simple. Very often it is as simple as
- Extract Method (automated refactoring)
- Create class and add it as a member of the existing class
- Move Method (automated refactoring)



