vendredi 3 mai 2019

Mob-programming, l'histoire d'une équipe

J'ai eu la chance d'interviewer une équipe qui fait du mob-programming pour le travail quotidien. Personnellement j'en ai fait souvent lors des coding-dojos, mais jamais pendant une longue durée dans un projet, c'était donc pour moi une excellente opportunité de bénéficier de leur expérience! Comme j'ai adoré ce petit échange d'une heure avec cette équipe très épanoui et fier de leur travail, je vous partage cher lecteur une version condensé en espérant que vous trouverez cela aussi utile que moi.



Comment cela a-t-il commencé?

Au début il y a avait qu'un développeur, et avec l'arrivée de deux autres on voulait essayer le mob rien qu'en mode apprentissage. On pouvait ainsi continuer à livrer tout en enseignant l'environnement technique et fonctionnel. "C'est bien plus agréable que de lire des docs" Remarque l'un des développeurs!

C'était très progressif, mais au bout de quoi, peut-être 3 semaines les nouveaux étaient opérationnels et participaient à pied d'égalité. Cela fait environ 9 mois maintenant et depuis nous avons intégré une nouvelle personne. La nouvelle personne a aussi beaucoup apprécié.

Cette nouvelle personne connaissant un peu moins la stack et les méthodes de développement (souvent du TDD) il a beaucoup apprécié le mob et notamment le fait de forcer le passage au clavier, pendant 7-10 minutes à la fois. Quand on est obligé comme ça on est obligé de s'accrocher et on progresse très très vite.
Il a été naturel de continuer le mob même après cette phase de montée en compétences

Justement, je suis curieux, faites-vous du mob tout le temps?

Non, on travaille aussi souvent en pair-programming, et même tout seul parfois. C'est assez naturel de switcher entre l'un et l'autre.

Qu'est-ce qui fait que vous choisissez le mob ou le pair ou le solo.

Le mob c'est lorsqu'il y a un peu de complexité, quand on sent qu'il y aura pas mal de discussion. Si quelque chose est très clair, qu'il n'y a pas trop de questions à se poser on va le faire seul ou à deux. Le choix se fait assez naturellement.

Quels sont d'après vous les bénéfices du mob?

Le code est bien meilleur en mob, on va tout de suite faire une remarque qui va être pris en compte sans perte de temps. Souvent c'est des choses qu'on aura même pas pris la peine de remonter lors d'un code-review.
Parfois on s'est retrouvé à même annuler une story suite à une discussion survenue dans le mob. C'était pas si facile de gérer ceci dans le code et c'était discutable d'un point de vue métier. Si quelqu'un l'avait fait seul on peur qu'il aurait juste foncé sans se poser ce genre de question.

<< Et là le PO a très envie d'intervenir :) >>

- Oui le truc le plus génial c'est que maintenant le dev plutôt js se retrouve à faire un peu d'embarqué (seul) et du coup je n'ai plus à planifier un petit peu de ceci et un peu de cela pour que tout le monde soit occupé dans l'équipe. Je peux me soucier de ce qu'il faut fonctionnellement!

- Effectivement ça doit faciliter les absences aussi, quelque part ça crée automatiquement une équipe pluri-disciplinaire

- Exactement!

Est-ce qu'il y a eu des tensions à gérer?

Oui, d'un point de vue matériel une fois qu'on était lancés, on s'est rendu compte qu'il fallait acheter un grand écran de qualité et on a fait des modifications à un bureau pour qu'il n'y ait pas de gêne pour s'approcher, genre des box à tiroirs.

Sinon dans l'équipe il y a beaucoup de bienveillance donc il n'y a jamais de problème de ce point de vue là. Par contre c'est assez intense et après une journée de mob on sent qu'on a travaillé! On n'a pas de pauses programmés sauf un peu le matin et en début d'après-midi et ça marche bien comme ça. Si quelqu'un n'est pas à fond tout le temps ce n'est pas très grave non plus.


---

Merci beaucoup à Damien, Romain, Sylvain, Benjamin et Vincent d'avoir partagé toute cette expérience. J'ai pas mal pratiqué dans des dojos, mais je n'ai pas réussi à mettre en place le mob à ce point dans un projet et ce genre de retour m'aide. Que vous continuez à prendre autant de plaisir dans le travail!

mardi 2 avril 2019

In cognitive psychology is refactoring a cost or a benefit?


Did you ever get frustrated when someone refactored your code? Or did you refactor someones code just to find out that the original developer wasn't all too happy about it?  This certainly happened to me a few times. Here's my understanding of what's happening from the point of view of cognitive psychology.

In cognitive psychology there's the term Long-Term Memory (LTM), which is roughly what we usually call just memory. What's interesting with our LTM is that it's optimised for storing large amounts of data, but not for changing existing data.

When we refactor some code we're forcing the developers knowing the code to rewrite their long-term memory. Remember that LTM is made to store a lot but not to be updated. That's a cost we're imposing on the original author. Sure the intention is to make future features cheaper to implement, but that's still a certain cost vs a potential benefit, later.

Given this we can better understand the frustration that a developer might feel when his/her code is thoroughly refactored. The bigger the change the higher the cost for the developers who know the code. In particular if the only motivation for changing the code is to make it cleaner or better, then that frustration might well be justified. After all better for whom? Certainly not for the original developer!

On the other hand whenever we have to evolve the code we're forced to rewrite the code and the corresponding LTM anyway, and if the code is not very well decoupled then it is quite unclear what part of our mental model of the code has to be rewritten. Should our brain just hang on to the original image or replace it or a part of it? The resulting LTM rewrite is probably imprecise, or requires more effort. The more complex the code, the harder it is to remodel and if it contains accidental complexity, we pay accidental remodelling cost. In short, with bad code that keeps changing, it's expensive to maintain a good mental model of the code in our long term memory.

If instead it was implemented respecting the principles of Single Responsibility Principle (small cohesive parts) and Open-Closed Principle (for new features code is added, instead of changed) then for any change in functionality we'd only have to swap one well identified part of the code. It becomes clear to our brain which part has to be rewritten in LTM, hence the cost of a rewrite is low. By respecting the principles of SRP and OCP we minimise the cost of maintenance in our LTM.

Conclusion and disclaimer


Cognitive psychology tells us there's an additional cost of refactoring in the form of (cache) invalidation of our mental model of the code. Of course this doesn't mean we should avoid refactoring as it also tells us that we need well factored code in order to minimise the cost as new features get added. By understanding the forces at play we can better choose when and what to refactor.

I'm nowadays very wary of refactoring code that doesn't need new behaviour. It hasn't always been so, indeed for several years I happily refactored code just because I could. Learning the basics of cognitive psychology has thought me to concentrate refactoring efforts to whenever I need to change the code anyway.

As a last word, there are valid reasons for refactoring code without a need for change. For instance for readability: naming things, extracting methods. Another good example is removing accidental complexity.

Would you like to hear more about this? Like how our LTM is feed through Chunking and Short Term Memory and how to optimise for that?

jeudi 3 janvier 2019

Testability trick - Replace static initialiser with lazy initialiser

A simple 4-step refactoring to make code more testable.

Static initialisers are a major hurdle for testing. If you have a static initialiser that for instance performs a request to the database then you cannot access that class in a unit test. Let alone mock it. So even if you're trying to test some other class, you cannot, since the offending class is contaminating every use of it with non testability. You want to make sure to remove the static initialiser so that other classes can be tested in isolation.


The solution is to replace the static initialiser with a lazy initialiser. This will allow you to load the class for mocking. You'll probably have to also replace a static method by an instance method in order to avoid calling the real method and so properly test classes that are calling the offending class, but first things first.

Assuming that your static initialiser is initialising a static field of your class:
  1. Encapsulate the access to the field with a simple getter
  2. Use the *Extract Method* refactoring to extract all the code from the static initialiser
  3. In the getter initialise the field *if it is null* by calling the extracted method 
  4. Delete the static initialiser
Yep it's that simple! :o)

Your next step will likely be to replace the public methods using this getter by instance methods so that those can be tested (example).

Let's have a look at an example of the code before refactoring

And now here's the refactored code. Steps 1 and two are made by automated refactorings.

Having done this we can simply add an instance method as a proxy to the static method, then use the instance method instead of the static method as referred to above .


mardi 11 décembre 2018

Continous delivery predicts organisational performance

This spring Nicole Forsgren, Jez Humble and Gene Kim published a vulgarisation of their four-year research endeavour into the impacts of Continuous delivery on the organisation. The book is called Accelerate - the IT revolution. Starting with intuition based on years of first hand experience they took on the task of formalising their assumptions to be able to test using research based on surveys. It turns out that many of the assumptions were correct but there were a few surprises.


Continuous delivery predicts organisational performance

The baseline is that Continuous delivery gives software delivery performance, which in turn is a predictor for organisational performance. This is a  key finding. It gives us confidence that we're very likely to get substantial bottom-line benefits if we invest into improving continuous delivery.

There are a few other benefits established by the research team.
Continuous delivery also reduces the amount of rework that has to be done, in fact high performers spend as much as 22% more time on New work when compared to low performers. Interestingly they also spend less time in meetings.

Continuous delivery also has a good impact on identity, meaning that people identify with their company. It also gives us less burnout and less deployment pain. Not surprisingly it also has a great impact on job satisfaction

Continuous delivery also puts pressure on the organisation to become more healthy with regard to how information flow between people and departments. They use the concept of Westrum organisational culture. In this sense it acts as a regulator towards the enterprise gangrene of power-struggle between managers.
Fruit you can expect when you nurture the roots of the continuous delivery tree

But let's have a look at the key finding, and what they mean by Continuous delivery, Software delivery performance and Organisational performance.

Continuous delivery

This is the practice of teams independently delivering into production safely, quickly and sustainably. The key principles here are
  • Quality inside
  • Small batches
  • Computers do repetitive stuff, people solve problems
  • Continuous improvement
  • Everyone responsible (for the global outcome)

The concrete practices that have been found to have a strong impact on the level of continuous delivery are

  • Version Control
    • Including configuration data and deployment tooling
  • Deployment automation
  • Continuous integration
  • Trunk-Based development
    • Branches are very, very short-lived
  • Test automation
    • Including that the majority of tests can easily be run on a local dev machine
  • Test data management
  • Shift left on security
    • security is built in as features are developed, as supposed to later.
  • Loosely coupled architecture
  • Empowered teams
    • Teams make most decisions without outside approval
  • Monitoring
  • Proactive notification

Software delivery performance

This means that we go quickly from idea to production which is good for minimising time to market. That we deploy frequently, which is good for developing just enough and have less features that are rarely or never used. That whenever we do introduce a bug or some down time it is quickly restored and finally how often we deliver bugs.

  • Lead time
  • Deployment frequency
  • Mean time to restore
  • Change fail percentage

Organisational performance

This the basic investors KPI, how profitable is the company, how  productive is it and how big a market share does it have. Basically what we need to motivate top management.

Research methods

I still have some questions as to how they distinguish between correlation and causation. While they do explain this in the book, my knowledge in statistics and research methods does not allow me to judge their explanation

Conclusion

Scientific findings establish a predictive relationship from continuous delivery to organisational performance. Going towards continuous delivery you can expect to get organisational performance. In particular any "Continuous delivery" transformation could use this as an overarching goal, as it is both likely to succeed and focuses on outcomes, rather than practices. You also get happier employees which in turn will fuel the organisational performance.




mardi 9 octobre 2018

Obtaining time for training and going to conferences

I know some employees that’d like to train more, to go to conferences, present at conferences and train during working hours. Few employers allow that to the extent that the employee would want to, some don’t even feel entitled to order books on behalf of their company. This generates frustration, and to me inefficiency at work, because developers need to continuously learn a lot and learn with a wider perspective than only the working environment can ever offer.


I’ve seen this tension and frustration in just about every company, from high profile consulting agencies where training is encouraged and expected, still one or two individuals would prefer to spend even more time training and preparing conference presentations, to some low profile consulting agencies where one boss explained to me: 
I have a problem with letting people train a lot. The company makes an investment through training fees and non billed time. The return on investment is negative, because the more they learn the greater the salary they can get elsewhere, but I can’t pay them much more because developer fees are limited. No matter the skill level I can’t charge above a certain level, so the more I invest the sooner they’ll leave
Now that’s sad, really really sad, but what would you do if this was your company?
Interestingly company owners never have a problem with their personal balance, neither do freelance developers. Why? It’s not because they’re special people in any sense. It’s because they are in a self regulating system. The more they train the less they "produce" in the short term, training is an "investment" in the future and they both reap the benefits and pay the bill. The system will balance without authoritarian decision and consequent frustration.


https://pxhere.com/en/photo/1435901

Now I have a bold idea both for business owners and for employees negotiating a new job. It came to me several years ago when a client wanted to hire me as an employee instead of as a contractor. The job was interesting so I asked myself what do I value as a freelance, what exactly do I like about it? It became very clear to me that I liked to have the freedom to decide. In particular what conferences I’d go to, what books I’d buy, when I needed to be away from work to train. So I stated my conditions: 25 days a year of training and going to and/or speaking at conferences with a budget of max 10k€ on training courses and travel expenses. After that we could negotiate salary, making it very easy for the future employer to calculate the total cost, salary, expenses, non-project time etc and compare it to the benefits of my activities. Naturally they had never encountered a demand like it before, nevertheless it was easily accepted. While I never ended up working with them for other reasons, I was confident that I wouldn’t have felt feel frustrated had I ended up working there.

As you can see I value time for training a lot, but not everyone does to that extent and that’s perfectly OK. We’re not all the same, some people prefer day to day work because lets face it it can be very interesting, and some value maximising salary. The point here is to give the opportunity to everyone to choose how much they’re investing in the future and how much we’re cashing out now.
Using this clear deal of clearly reserving the expected time and budget for knowledge development, people can even use companies like the low profile consulting agency as trampolines for their career, accepting lower salary in return for greater investment, a productive partnership.
In short when an employee goes to training or prepare a presentation the company benefits a lot from it, but so does the employee. When benefits are mutual so should cost be, otherwise heavy investment is not sustainable. So following this idea of shared costs, almost anyone can find a good balance with almost any company.

www.publicdomainpictures.net/view-image.php?image=136005
Possibly there’s even more value to it. Some people haven’t quite internalised that we have to learn more than we can learn by daily work. And I think it can help them, as well as the organization as a whole, to ask people during the hiring process
How much training etc would suit you? We will provide a minimum, but we can also help you if you’d like more.
I suspect such a question could help people think about it and take responsibility for their future development.


What do you think? Have you tried something similar? If you know of people and companies who does this or would like to try it yourself, I’d love to hear about it!

mercredi 4 juillet 2018

Type Driven Development pattern: Small types


TLDR; Small types in type driven development facilitates composability much like small objects do in OO. By small types I mean few constructors and little data in each.

One of my first experiences in Idris was to try to implement a FizzBuzz where the types would be so strong that they'd ensure  the code could only be correctly implemented.

FizzBuzz is a game where the input is a number between 1 and 100. The output is a string, "Fizz" if the number is divisible by 3. "Buzz" if the number is divisible by 5. "FizzBuzz" if it is both divisible by 3 and 5 and just the number otherwise. eg counting from 1

1, 2, fizz, 4, buzz, fizz, 7, 8, fizz, buzz, ...

My first implemention enforces the correctness by taking as arguments proofs that the given number is either divisible by 3 or a proof that it is not divisible. That way can call the constructor Fizz if and only if you can provide proof of division by 3 and a proof of non division by 5.



So just by defining a type FizzBuzz and the signatures of the constructors of this type we have no possibility of making a mistake in the implementation. Nice! Here's are the types and signature of methods.



IF you're curious about the implementation it's here

Besides being a major challenge, for me, in mastering dependent types and understanding that types can act as proofs, it actually worked out quite OK. Certainly it does not allow for incorrect code, so it was a successful experience. Sure it is a bit of verbose and contains a bit of pseudo-duplication.

But not extensible
Now there's an extension to FizzBuzz, namely Bang. Bang is the word for every multiple of 7, for instance given the number 21 we should return FizzBang. Now without Bang there are 4 possible results, Fizz, Buzz, FizzBuzz and the number. Now here's where things become interesting because with Bang there are 8, so the problem of verbosity and pseudo-duplication gets a lot worse. Clearly the first solution isn't very extensible

A better solution
A different approach is to decompose the type FizzBuzz into smaller orthogonal types. Lets consider the type Fizz (either a IsFizz or a Not IsFizz), the type Buzz, then FizzBuzz can be modeled as a tuple (pair) of Fizz an Buzz (the full code).



If we add the functionality of Bang then all we have to do is create a new type Bang, and a new composed type a 3-tuple of Fizz, Buzz and Bang. We don't have to break the existing type FizzBuzz nor the former function, we could possibly even keep the former method, a good example of the open-closed principle. Open-closed-principle with dependently typed code!

Possibly we'd fear that by making the types less closed we'd be able to code an incorrect solution to fizzbuzz. But that's still not possible.

Learnings
Keeping types small in the sense that they contain little data (few arguments) and have few constructors, favours reuse through composition. It might seem obvious in hindsight, but I discovered this much in the same way that I discovered the use of small objects in OO.

Some people say that strongly typed languages like Idris doesn't allow for extension, that they'd be closed by design. What I learned from this experience is that while that certainly applies to a type and functions on existing types, we can still compose types in new ways. Given of course that our types are small enough.

jeudi 17 mai 2018

Bug generator: Non constrained construction


A bug generator is a style of code that is likely to contain bugs or produce bugs in the future as the code is extended by making them more likely. This is of course an anti-pattern. There are corresponding Prevention Patterns, basically less error-prone alternatives. Now that the term is defined, lets dive into today's bug generator, namely non constrained construction.


Non constrained construction means that it is possible to construct an invalid object. Examples are 1) mandatory parameters are set after construction using a setter 2) No validations in the constructor, for instance instantiating a PhoneNumber using any string. 3) Several parameters of the same type in the constructor. Inversion of the order parameters becomes likely. Example the constructor takes 3 strings


Bug: Object created without mandatory parameter
Some instance variables are added with setters. There is no guarantee that every user of the object thought of setting at least the mandatory ones. One single instantiation without the mandatory parameter suffice to create a bug, that takes the form of null pointer exceptions or a reference to undefined (JS) at  runtime. It can also take the expression of inconsistent behaviour if the depending code handles null as a special flag (see Null-Flag bug-generator). Alternatively it complexifies all the client code with checks to see if the parameter has been set. Remember those if (object != null) { .. } blocks?

Prevention pattern: All mandatory parameters in constructor
It is extraordinary easy to prevent this type of bug, simply by enforcing all mandatory parameters in the constructor(s). 

If there are several combinations of parameters we can use  several constructors or for languages that allows only one constructor we can use static factory methods, that enumerate the valid ways instantiating an object. e.g.

    
private constructor(mainCourse, starter?, dessert?) {...}

public static withoutDessert(mainCourse, starter) {
return new Menu(mainCourse, starter)
}

public static withoutStarter(mainCourse, dessert) {
 return new Menu(mainCourse, null, dessert)
}

Bug: Object contains invalid data
We might instantiate a phone number assuming that we always feed a string containing the country code country code. So when we try to call this number we get a failure or we call someone in another country. Likewise we might accept some IBAN number without validating the key. Later when we post it to some webservice that does validation, then we need to report an error to the user in an asynchronous way like sending an email, sms etc. Handling bad data late is always more costly than just rejecting it on input.

Prevention pattern: assertions in the constructor
Do validations in the constructor. You can mostly get away with throwing an error and only catching it at the top level, like a generic error handler, a very common pattern in the world of REST services is to map Error objects to HTTP status codes via a generic handler.

The reason we prefer doing the validations in the constructor rather than doing them before construction is because it  guarantees that the validation is made.

Bug: Constructor parameters are switched

For instance our menu from above takes strings mainCourse, starter and dessert as parameters. It is very easy to switch the order

Prevention pattern: Type parameters 
Introduce distinct types for each parameter i.e. MainCourse, Starter and Dessert. This makes it impossible. While this might seem a bit clunky in some mainstream languages it's also a step towards the removal of primitives which adresses another problem, namely the bug generator Primitive Obsession.

Prevention pattern: pass a map/dictionnary or use a parameter object or yet a builder
if each parameter has a name that is visible in the code we reduce the chance of a bug. It is harder to put something in front of the wrong name, like

    { dessert: 'pizza royale', mainCourse: 'chocolat mousse'} 

than it is to make a mistake of order. You might recognize the concept of Connascence of name vs position

Bug: Object not fully initialized before use
Let's imagine an object where we have to call an initialisation method after instantiation like the well known init(). The code gives no guarantee that this will always be done For instance forgot to call init(). The effect of this bug is not dramatic as  in most cases it'll just confuse the developer for a long time as to why the app doesn't work correctly. It rarely slips into production, just slows down the development.

Prevention pattern: call init() in the constructor
Whenever possible.

Prevention pattern: use a factory method
So that the fragile sequence is only in one place. Or refactor so that you pass the result of the init() method to the constructor. i.e the init() method becomes static and/or is moved away from the class all together. e.g.

public constructor(resultOfInit) {}

Prevention pattern: when two objects references each other
When there's a cyclic dependency between two objects, this can be eliminated on the type level by interfaces but the runtime dependency might remain. Then one must be instantiated before the other. We have at least two options for solving this. 1) It might be possible to extract a third object on which the two others depend on, thus eliminating the cyclic dependency, but more often 2) we make this more explicit, like Spring's @PostConstruct. The benefit is that it becomes easy to find all such objects.

There's no particular conclusion to make. It documents the problems and a range of alternative solutions. 

Credits to Peter Kofler whith whom we detailed the bugs and prevention patterns