Record of experiments, readings, links, videos and other things that I find on the long road.
Registro de experimentos, lecturas, links, vídeos y otras cosas que voy encontrando en el largo camino.
Wednesday, December 30, 2020
Books I read 2020
- Waltzing with Bears: Managing Risk on Software Projects, Tom DeMarco, Timothy R. Lister
- An Armenian Sketchbook (Добро вам!), Vasily Grossman
- La flor púrpura, Chimamanda Ngozi Adichie
- El día 3, Miguel Á. Giner Bou, Cristina Durán, Laura Ballester
- A Practical Guide to Testing in DevOps, Katrina Clokie
- La espada de Damocles (Finstere Zeiten: Zur Krise in Griechenland), Petros Márkaris
- The Phoenix Project: A Novel About IT, DevOps, and Helping Your Business Win, Gene Kim, Kevin Behr, George Spafford
- Bartleby, el escribiente (Bartleby, the Scrivener: A Story of Wall Street), Herman Melville
- Señora de rojo sobre fondo gris, Miguel Delibes
- Neverwhere, Neil Gaiman
February
- Personal Kanban: Mapping Work, Navigating Life, Jim Benson, Tonianne DeMaria Barry
- The Art of Peace, Morihei Ueshiba
- Theory of Constraints, Eliyahu M. Goldratt
- Johnny Cash: I See a Darkness, Reinhard Kleist
March
- The Amazing Adventures of Kavalier and Clay, Michael Chabon
- Vampir, Joann Sfar (2nd time)
- Lean Software Development: An Agile Toolkit, Mary Poppendieck, Tom Poppendieck
- Dune, Frank Herbert
- Stoner, John Williams
April
- The Wanderer, Fritz Leiber
- Dune Messiah, Frank Herbert
- Bloodchild, Octavia E. Butler
- Children of Dune, Frank Herbert
May
- Agile Coaching, Rachel Davies, Liz Sedley
- Guía de la buena comunicación, Gerardo Sánchez Lozano
- Go Tell It on the Mountain, James Baldwin.
- Ikigai: The Japanese secret to a long and happy life (audiobook), Héctor García, Francesc Miralles
- Yes to Life: In Spite of Everything, Viktor E. Frankl
June
- Fooled by Randomness: The Hidden Role of Chance in Life and in the Markets Rate (audiobook), Nassim Nicholas Taleb
- A Princess of Mars (audiobook), Edgar Rice Burroughs
- Good Omens: The Nice and Accurate Prophecies of Agnes Nutter, Witch (audiobook), Terry Pratchett, Neil Gaiman
- God Emperor of Dune, Frank Herbert
- Ironmind: Stronger Minds, Stronger Bodies: Stronger Minds, Stronger Bodies, Randall J. Strossen
- Man's Search for Meaning (audiobook), Viktor E. Frankl (2nd time)
- Heretics of Dune, Frank Herbert
- Chapterhouse: Dune, Frank Herbert
July
- Moonglow, Michael Chabon
- Managing Technical Debt: Reducing Friction in Software Development, Philippe Kruchten, Robert Nord, Ipek Ozkaya
- Alone in Berlin (Jeder stirbt für sich allein), Hans Fallada
- Building Maintainable Software, Java Edition, Joost Visser
- The Art of Taking Action: Lessons from Japanese Psychology, Gregg Krech
- The Cat's Table, Michael Ondaatje
- A solas, Silvia Congost
- Starship Troopers, Robert A. Heinlein
August
- Medio sol amarillo (Half of a Yellow Sun), Chimamanda Ngozi Adichie
- The Lady Astronaut of Mars, Mary Robinette Kowal
- How to Be a Stoic: Using Ancient Philosophy to Live a Modern Life (audiobook), Massimo Pigliucci
- Flowers for Algernon, Daniel Keyes
- Una partida de ajedrez, Stefan Zweig
- A Country Doctor's Notebook (Записки юного врача), Mikhail Bulgakov
- Being Wrong: Adventures in the Margin of Error, Kathryn Schulz
- Play It as It Lays, Joan Didion
- Panza de burro, Andrea Abreu
- The Power, Naomi Alderman
September
- I Have No Mouth, and I Must Scream: Stories, "I Have No Mouth, and I Must Scream", “Big Sam Was My Friend”, “Eyes of Dust”, “World of the Myth”, “Lonelyache”, “Delusion for a Dragon Slayer”, and “Pretty Maggie Moneyeyes”, Harlan Ellison
- Functional-Light JavaScript: Pragmatic, Balanced FP in JavaScript, Kyle Simpson
- Professor Frisby's Mostly Adequate Guide to Functional Programming, Brian Lonsdorf
- Enchiridion (audiobook), Epictetus
October
- 10% Happier: How I Tamed the Voice in My Head, Reduced Stress Without Losing My Edge, and Found Self-Help That Actually Works, Dan Harris
- Cat's Cradle, Kurt Vonnegut
- Enchiridion, Epictetus (2nd time)
- To Be Taught, If Fortunate, Becky Chambers
- Sing, Unburied, Sing, Jesmyn Ward
- The 5 Elements of Effective Thinking (audiobook), Edward B. Burger, Michael Starbird
- The Martian Chronicles, Ray Bradbury
- The DevOps Handbook: How to Create World-Class Agility, Reliability, and Security in Technology Organizations, Gene Kim, Jez Humble, Patrick Debois, John Willis
- Overcoming Poor Posture: A Systematic Approach to Refining Your Posture for Health and Performance, Steven Low, Jarlo Ilano
- No Time to Spare: Thinking About What Matters, Ursula K. Le Guin
- El castillo blanco (Beyaz Kale), Orhan Pamuk
November
- Stamboul Train, Graham Greene
- El gatopardo (Il Gattopardo), Giuseppe Tomasi di Lampedusa
- Journal 1935-1944 (Jurnal, 1935-1944), Mihail Sebastian
- Cuando el desierto florece (Splitting the Arrow), Prem Rawat
- Rivers of London, Ben Aaronovitch
December
- More Than Human, Theodore Sturgeon
- Moon Over Soho, Ben Aaronovitch
- The Effluent Engine, N.K. Jemisin
- Whispers Under Ground, Ben Aaronovitch
- Broken Homes, Ben Aaronovitch
- Foxglove Summer, Ben Aaronovitch
- The Furthest Station, Ben Aaronovitch
- Americanah, Chimamanda Ngozi Adichie
- The Hanging Tree, Ben Aaronovitch
- Lies Sleeping, Ben Aaronovitch
- Tales From The Folly, Ben Aaronovitch
- The October Man, Ben Aaronovitch
- False Value, Ben Aaronovitch
Monday, December 14, 2020
Interesting Talk: "Body Embracement and Personal Power"
Interesting Documentary film: "The Backbone of Night, Cosmos (7)"
Interesting Documentary film: "Travellers' Tales, Cosmos (6)"
Interesting Documentary film: "Blues for a Red Planet, Cosmos (5)"
Interesting Documentary film: "Heaven and Hell, Cosmos (4)"
Interesting Documentary film: "The Harmony of the Worlds, Cosmos (3)"
Interesting Talk: "Coming Closer to Ourselves"
Interesting Talk: "The Noble Journey From Fear to Fearlessness"
Interesting Podcast: "Optimize Your Microbiome"
Interesting Podcast: "Weight Training for Women Balances Hormones"
Interesting Podcast: "Indigenous Thinking for Troubled Times"
Interesting Talk: "Learning to Respond, Not React"
Interesting Talk: "Balancing Acceptance and Change: DBT and the Future of Skills Training"
Interesting Talk: "Radical Acceptance Revisited"
Interesting Podcast: "Deadlifting Your Way to Metabolic Flexibility"
Interesting Podcast: "Muscle Growth Science, mTOR & Leucine"
Interesting Talk: "Mating in Captivity: Reconciling Intimacy and Sexuality"
Interesting Documentary film: "The Kiwi Way - Steven Adams' New Zealand"
Interesting Podcast: "Are we eating too much (or not enough) protein for good health?"
Sunday, December 13, 2020
Interesting Podcast: "Muscle-centric medicine"
Monday, November 30, 2020
Solving the Beverages Prices Refactoring kata (1): composition over inheritance
Introduction.
We are going to show a possible solution to the Beverages Prices Refactoring kata that we developed recently with some people from Women Tech Makers Barcelona with whom I’m doing Codesai’s Practice Program twice a month.
The Beverages Prices Refactoring kata shows an example of inheritance gone astray. The initial code computes the price of the different beverages that are sold in a coffee house. There are some supplements that can be added to those beverages. Each supplement increases the price a bit. Not all combinations of drinks and supplements are possible.
As part of the kata, we are asked to add an optional cinnamon supplement that costs 0.05€ to all our existing catalog of beverages. We are also advised to refactor the initial code a bit before introducing the new feature. Let’s see why.
The initial code.
To get an idea of the kind of problem we are facing, we’ll have a look at the code. There are 8 files: a Beverage
interface and 7 classes, one for each type of beverage and one for each allowed combination of beverages and supplements.
A closer look reveals that the initial design uses inheritance and polymorphism to enable the differences in computing the price of each allowed combination of beverage and supplements. This is the inheritance hierarchy:
If that diagram is not enough to scare you, have a quick look at the unit tests of the code:
First, we make the change easy[1].
Given the current design, if we decided to add the new feature straight away, we would end up with 14 classes (2 times the initial number of classes). If you think about it, this would happen for each new supplement we decided to add. It would be the same for each new supplement we were required to add: we would be forced to double the number of classes, that means that to add n supplements more would mean multiplying the initial number of classes by 2n.
This exponential growth in the number of classes is a typical symptom of a code smell called Combinatorial Explosion[2]. In this particular case the problem is caused by using inheritance to represent the pricing of beverages plus supplements.
In order to introduce the new cinnamon supplement, we thought sensible to do a bit of preparatory refactoring first in order to remove the Combinatorial Explosion code smell. The recommended refactoring for this code smell is Replace Inheritance with Delegation which leads to a code that uses composition instead of inheritance to avoid the combinatorial explosion. If all the variants[3] (supplements) keep the same interface, we’d be creating an example of the decorator design pattern[4].
The decorator pattern provides an alternative to subclassing for extending behavior. It involves a set of decorator classes that wrap concrete components and keep the same interface that the concrete components. A decorator changes the behavior of a wrapped component by adding new functionality before and/or after delegating to the concrete component.
Applying the decorator pattern design to compute the pricing of beverages plus supplements, the beverages would correspond to the concrete components, tea, coffee and hot chocolate; whereas the supplements, milk and cream would correspond to the decorators.
We can obtain the behavior for a given combination of supplements and beverage by composing supplements (decorators) with a beverage (base component).
For instance, if we had the following WithMilk
decorator for the milk supplement pricing,
we would compose it with a Tea
instance to create the behavior that computes the price of a tea with milk:
A nice thing about decorators is that, since they have the same interface as the component they wrap, they are transparent for the client code[6] which never has to know that it’s dealing with a decorator. This allows us to pass them around in place of the wrapped object which makes it possible to compose behaviors using as many decorators as we like. The following example shows how to compose the behavior for computing the price of a coffee with milk and cream[7].
After applying the Replace Inheritance with Delegation refactoring we get to a design that uses composition instead of inheritance to create all the combinations of supplements and beverages. This fixes the Combinatorial Explosion code smell.
You can have a look at the rest of the test after this refactoring in this gist.
Then, we make the easy change.
Once we had the new design based in composition instead of inheritance in place, adding the requested feature is as easy as creating a new decorator that represents the cinnamon supplement pricing:
Remember that using the initial design adding this feature would have involved multiplying by two the number of classes.
What have we gained and lost with this refactoring?
After the refactoring we have a new design that uses the decorator design pattern. This is a flexible alternative design to subclassing for extending behavior that allows us to add behavior dynamically to the objects wrapped by the decorators.
Thanks to this runtime flexibility we managed to fix the Combinatorial Explosion code smell and that made it easier to add the new feature. Now, instead of multiplying the number of cases by two, adding a new supplement only involves adding one new decorator class that represents the new supplement pricing. This new design makes the client code open-closed to the axis of change of adding new supplements.
On the flip side, we have introduced some complexity[8] related to creating the different compositions of decorators and components. At the moment this complexity is being managed by the client code (notice the chains of new
s in the tests snippets above).
There’s also something else that we have lost in the process. In the initial design only some combinations of beverages and supplements were allowed. This fact was encoded in the initial inheritance hierarchy. Now with our decorators we can dynamically add any possible combination of beverages and supplements.
All in all, we think that the refactoring leaves us in a better spot because we’ll be likely required to add new supplements, and there are usual improvements we can make to the design to isolate the client code from the kind of complexity we have introduced.
Conclusion.
We have shown an example of preparatory refactoring to make easier the addition of a new feature, and learned about the Combinatorial Explosion code smell and how to fix it using the decorator design pattern to get a new design in which we have protected the client code[9] against variations involving new supplements.
In a future post we will show how to encapsulate the creation of the different compositions of decorators and components using builders and/or factories to hide that complexity from client code, and show how we can limit again the allowed combinations that are part of the menu.
Aknowledgements.
I’d like to thank the WTM study group, and especially Inma Navas for solving this kata with me.
Thanks to my Codesai colleagues and Inma Navas for reading the initial drafts and giving me feedback and to Lisa Fotios for her picture.
Notes.
[1] This and the next header come from Kent Beck’s quote:
“For each desired change, make the change easy (warning: this may be hard), then make the easy change”
[2] You can find this code smell described in Bill Wake’s wonderful Refactoring Workbook.
[3] In this context variant means a variation in behavior. For instance, each derived class in a hierarchy is a variant of the base class.
[4] Have a look at the chapter devoted to the decorator design pattern in the great Head First Design Patterns. It’s the most didactic and fun explanation of the pattern I’ve ever found. This kata is heavily inspired in the example used in that chapter to explain the pattern.
[5] We could have also solved this problem composing functions instead of objects, but we wanted to practice with objects in this solution of the kata. That might be an interesting exercise for another practice session.
[6] In this context client code means code that uses objects implementing the interface that both the components and decorators implement, which in the kata would correspond to the Beverage
interface.
[7] Also known as a “cortado leche y leche” in Gran Canaria :)
[8] Complexity is most often the price we pay for flexibility. That’s why we should always assess if the gains are worth the price.
[9] Protected variations is another way to refer to the open-closed principle. I particularly prefer that way to refer to this design principle because I think it is expressed in a way that relates less to object orientation. Have a look at Craig Larman’s great article about it: Protected Variation: The Importance of Being Closed
References.
- The Beverages Prices Refactoring kata: a kata to practice refactoring away from an awful application of inheritance
- Replace Inheritance with Delegation
- Protected Variation: The Importance of Being Closed, Craig Larman
- Open-closed Principle
- Refactoring Workbook, William C. Wake
- Head First Design Patterns, Eric Freeman, Kathy Sierra, Bert Bates, Elisabeth Robson
Books I read (January - November 2020)
- Waltzing with Bears: Managing Risk on Software Projects, Tom DeMarco, Timothy R. Lister
- An Armenian Sketchbook (Добро вам!), Vasily Grossman
- La flor púrpura, Chimamanda Ngozi Adichie
- El día 3, Miguel Á. Giner Bou, Cristina Durán, Laura Ballester
- A Practical Guide to Testing in DevOps, Katrina Clokie
- La espada de Damocles (Finstere Zeiten: Zur Krise in Griechenland), Petros Márkaris
- The Phoenix Project: A Novel About IT, DevOps, and Helping Your Business Win, Gene Kim, Kevin Behr, George Spafford
- Bartleby, el escribiente (Bartleby, the Scrivener: A Story of Wall Street), Herman Melville
- Señora de rojo sobre fondo gris, Miguel Delibes
- Neverwhere, Neil Gaiman
February
- Personal Kanban: Mapping Work, Navigating Life, Jim Benson, Tonianne DeMaria Barry
- The Art of Peace, Morihei Ueshiba
- Theory of Constraints, Eliyahu M. Goldratt
- Johnny Cash: I See a Darkness, Reinhard Kleist
March
- The Amazing Adventures of Kavalier and Clay, Michael Chabon
- Vampir, Joann Sfar (2nd time)
- Lean Software Development: An Agile Toolkit, Mary Poppendieck, Tom Poppendieck
- Dune, Frank Herbert
- Stoner, John Williams
April
- The Wanderer, Fritz Leiber
- Dune Messiah, Frank Herbert
- Bloodchild, Octavia E. Butler
- Children of Dune, Frank Herbert
May
- Agile Coaching, Rachel Davies, Liz Sedley
- Guía de la buena comunicación, Gerardo Sánchez Lozano
- Go Tell It on the Mountain, James Baldwin.
- Ikigai: The Japanese secret to a long and happy life (audiobook), Héctor García, Francesc Miralles
- Yes to Life: In Spite of Everything, Viktor E. Frankl
June
- Fooled by Randomness: The Hidden Role of Chance in Life and in the Markets Rate (audiobook), Nassim Nicholas Taleb
- A Princess of Mars (audiobook), Edgar Rice Burroughs
- Good Omens: The Nice and Accurate Prophecies of Agnes Nutter, Witch (audiobook), Terry Pratchett, Neil Gaiman
- God Emperor of Dune, Frank Herbert
- Ironmind: Stronger Minds, Stronger Bodies: Stronger Minds, Stronger Bodies, Randall J. Strossen
- Man's Search for Meaning (audiobook), Viktor E. Frankl (2nd time)
- Heretics of Dune, Frank Herbert
- Chapterhouse: Dune, Frank Herbert
July
- Moonglow, Michael Chabon
- Managing Technical Debt: Reducing Friction in Software Development, Philippe Kruchten, Robert Nord, Ipek Ozkaya
- Alone in Berlin (Jeder stirbt für sich allein), Hans Fallada
- Building Maintainable Software, Java Edition, Joost Visser
- The Art of Taking Action: Lessons from Japanese Psychology, Gregg Krech
- The Cat's Table, Michael Ondaatje
- A solas, Silvia Congost
- Starship Troopers, Robert A. Heinlein
August
- Medio sol amarillo (Half of a Yellow Sun), Chimamanda Ngozi Adichie
- The Lady Astronaut of Mars, Mary Robinette Kowal
- How to Be a Stoic: Using Ancient Philosophy to Live a Modern Life (audiobook), Massimo Pigliucci
- Flowers for Algernon, Daniel Keyes
- Una partida de ajedrez, Stefan Zweig
- A Country Doctor's Notebook (Записки юного врача), Mikhail Bulgakov
- Being Wrong: Adventures in the Margin of Error, Kathryn Schulz
- Play It as It Lays, Joan Didion
- Panza de burro, Andrea Abreu
- The Power, Naomi Alderman
September
- I Have No Mouth, and I Must Scream: Stories, "I Have No Mouth, and I Must Scream", “Big Sam Was My Friend”, “Eyes of Dust”, “World of the Myth”, “Lonelyache”, “Delusion for a Dragon Slayer”, and “Pretty Maggie Moneyeyes”, Harlan Ellison
- Functional-Light JavaScript: Pragmatic, Balanced FP in JavaScript, Kyle Simpson
- Professor Frisby's Mostly Adequate Guide to Functional Programming, Brian Lonsdorf
- Enchiridion (audiobook), Epictetus
October
- 10% Happier: How I Tamed the Voice in My Head, Reduced Stress Without Losing My Edge, and Found Self-Help That Actually Works, Dan Harris
- Cat's Cradle, Kurt Vonnegut
- Enchiridion, Epictetus (2nd time)
- To Be Taught, If Fortunate, Becky Chambers
- Sing, Unburied, Sing, Jesmyn Ward
- The 5 Elements of Effective Thinking (audiobook), Edward B. Burger, Michael Starbird
- The Martian Chronicles, Ray Bradbury
- The DevOps Handbook: How to Create World-Class Agility, Reliability, and Security in Technology Organizations, Gene Kim, Jez Humble, Patrick Debois, John Willis
- Overcoming Poor Posture: A Systematic Approach to Refining Your Posture for Health and Performance, Steven Low, Jarlo Ilano
- No Time to Spare: Thinking About What Matters, Ursula K. Le Guin
- El castillo blanco (Beyaz Kale), Orhan Pamuk
November
- Stamboul Train, Graham Greene
- El gatopardo (Il Gattopardo), Giuseppe Tomasi di Lampedusa
- Journal 1935-1944 (Jurnal, 1935-1944), Mihail Sebastian
- Cuando el desierto florece (Splitting the Arrow), Prem Rawat
- Rivers of London, Ben Aaronovitch
Saturday, October 31, 2020
Books I read (January - October 2020)
- Waltzing with Bears: Managing Risk on Software Projects, Tom DeMarco, Timothy R. Lister
- An Armenian Sketchbook (Добро вам!), Vasily Grossman
- La flor púrpura, Chimamanda Ngozi Adichie
- El día 3, Miguel Á. Giner Bou, Cristina Durán, Laura Ballester
- A Practical Guide to Testing in DevOps, Katrina Clokie
- La espada de Damocles (Finstere Zeiten: Zur Krise in Griechenland), Petros Márkaris
- The Phoenix Project: A Novel About IT, DevOps, and Helping Your Business Win, Gene Kim, Kevin Behr, George Spafford
- Bartleby, el escribiente (Bartleby, the Scrivener: A Story of Wall Street), Herman Melville
- Señora de rojo sobre fondo gris, Miguel Delibes
- Neverwhere, Neil Gaiman
February
- Personal Kanban: Mapping Work, Navigating Life, Jim Benson, Tonianne DeMaria Barry
- The Art of Peace, Morihei Ueshiba
- Theory of Constraints, Eliyahu M. Goldratt
- Johnny Cash: I See a Darkness, Reinhard Kleist
March
- The Amazing Adventures of Kavalier and Clay, Michael Chabon
- Vampir, Joann Sfar (2nd time)
- Lean Software Development: An Agile Toolkit, Mary Poppendieck, Tom Poppendieck
- Dune, Frank Herbert
- Stoner, John Williams
April
- The Wanderer, Fritz Leiber
- Dune Messiah, Frank Herbert
- Bloodchild, Octavia E. Butler
- Children of Dune, Frank Herbert
May
- Agile Coaching, Rachel Davies, Liz Sedley
- Guía de la buena comunicación, Gerardo Sánchez Lozano
- Go Tell It on the Mountain, James Baldwin.
- Ikigai: The Japanese secret to a long and happy life (audiobook), Héctor García, Francesc Miralles
- Yes to Life: In Spite of Everything, Viktor E. Frankl
June
- Fooled by Randomness: The Hidden Role of Chance in Life and in the Markets Rate (audiobook), Nassim Nicholas Taleb
- A Princess of Mars (audiobook), Edgar Rice Burroughs
- Good Omens: The Nice and Accurate Prophecies of Agnes Nutter, Witch (audiobook), Terry Pratchett, Neil Gaiman
- God Emperor of Dune, Frank Herbert
- Ironmind: Stronger Minds, Stronger Bodies: Stronger Minds, Stronger Bodies, Randall J. Strossen
- Man's Search for Meaning (audiobook), Viktor E. Frankl (2nd time)
- Heretics of Dune, Frank Herbert
- Chapterhouse: Dune, Frank Herbert
July
- Moonglow, Michael Chabon
- Managing Technical Debt: Reducing Friction in Software Development, Philippe Kruchten, Robert Nord, Ipek Ozkaya
- Alone in Berlin (Jeder stirbt für sich allein), Hans Fallada
- Building Maintainable Software, Java Edition, Joost Visser
- The Art of Taking Action: Lessons from Japanese Psychology, Gregg Krech
- The Cat's Table, Michael Ondaatje
- A solas, Silvia Congost
- Starship Troopers, Robert A. Heinlein
August
- Medio sol amarillo (Half of a Yellow Sun), Chimamanda Ngozi Adichie
- The Lady Astronaut of Mars, Mary Robinette Kowal
- How to Be a Stoic: Using Ancient Philosophy to Live a Modern Life (audiobook), Massimo Pigliucci
- Flowers for Algernon, Daniel Keyes
- Una partida de ajedrez, Stefan Zweig
- A Country Doctor's Notebook (Записки юного врача), Mikhail Bulgakov
- Being Wrong: Adventures in the Margin of Error, Kathryn Schulz
- Play It as It Lays, Joan Didion
- Panza de burro, Andrea Abreu
- The Power, Naomi Alderman
September
- I Have No Mouth, and I Must Scream: Stories, "I Have No Mouth, and I Must Scream", “Big Sam Was My Friend”, “Eyes of Dust”, “World of the Myth”, “Lonelyache”, “Delusion for a Dragon Slayer”, and “Pretty Maggie Moneyeyes”, Harlan Ellison
- Functional-Light JavaScript: Pragmatic, Balanced FP in JavaScript, Kyle Simpson
- Professor Frisby's Mostly Adequate Guide to Functional Programming, Brian Lonsdorf
- Enchiridion (audiobook), Epictetus
October
- 10% Happier: How I Tamed the Voice in My Head, Reduced Stress Without Losing My Edge, and Found Self-Help That Actually Works, Dan Harris
- Cat's Cradle, Kurt Vonnegut
- Enchiridion, Epictetus (2nd time)
- To Be Taught, If Fortunate, Becky Chambers
- Sing, Unburied, Sing, Jesmyn Ward
- The 5 Elements of Effective Thinking (audiobook), Edward B. Burger, Michael Starbird
- The Martian Chronicles, Ray Bradbury
- The DevOps Handbook: How to Create World-Class Agility, Reliability, and Security in Technology Organizations, Gene Kim, Jez Humble, Patrick Debois, John Willis
- Overcoming Poor Posture: A Systematic Approach to Refining Your Posture for Health and Performance, Steven Low, Jarlo Ilano
- No Time to Spare: Thinking About What Matters, Ursula K. Le Guin
- El castillo blanco (Beyaz Kale), Orhan Pamuk
Sunday, October 18, 2020
Sleeping is not the best option
Introduction.
Some time ago we were developing a code that stored some data with a given TTL. We wanted to check not only that the data was stored correctly but also that it expired after the given TTL. This is an example of testing asynchronous code.
When testing asynchronous code we need to carefully coordinate the test with the system it is testing to avoid running the assertion before the tested action has completed[1]. For example, the following test will always fail because the assertion in line 30 is checked before the data has expired:
In this case the test always fails but in other cases it might be worse, failing intermittently when the system is working, or passing when the system is broken. We need to make the test wait to give the action we are testing time to complete successfully and fail if this doesn’t happen within a given timeout period.
Sleeping is not the best option.
This is an improved version of the previous test in which we are making the test code wait before the checking that the data has expired to give the code under test time to run:
The problem with the simple sleeping approach is that in some runs the timeout might be enough for the data to expire but in other runs it might not, so the test will fail intermittently; it becomes a flickering test. Flickering tests are confusing because when they fail, we don’t know whether it’s due to a real bug, or it is just a false positive. If the failure is relatively common, the team might start ignoring those tests which can mask real defects and completely destroy the value of having automated tests.
Since the intermittent failures happen because the timeout is too close to the time the behavior we are testing takes to run, many teams decide to reduce the frequency of those failures by increasing the time each test sleeps before checking that the action under test was successful. This is not practical because it soon leads to test suites that take too long to run.
Alternative approaches.
If we are able to detect success sooner, succeeding tests will provide rapid feedback, and we only have to wait for failing tests to timeout. This is a much better approach than waiting the same amount of time for each test regardless it fails or succeeds.
There are two main strategies to detect success sooner: capturing notifications[2] and polling for changes.
In the case we are using as an example, polling was the only option because redis didn’t send any monitoring events we could listen to.
Polling for changes.
To detect success as soon as possible, we’re going to probe several times separated by a time interval which will be shorter than the previous timeout. If the result of a probe is what we expect the test pass, if the result we expect is not there yet, we sleep a bit and retry. If after several retries, the expected value is not there, the test will fail.
Have a look at the checkThatDataHasExpired
method in the following code:
By polling for changes we avoid always waiting the maximum amount of time. Only in the worst case scenario, when consuming all the retries without detecting success, we’ll wait as much as in the just sleeping approach that used a fixed timeout.
Extracting a helper.
Scattering ad hoc low level code that polls and probes like the one in checkThatDataHasExpired
throughout your tests not only make them difficult to understand, but also is a very bad case of duplication. So we extracted it to a helper so we could reuse it in different situations.
What varies from one application of this approach to another are the probe, the check, the number of probes before failing and the time between probes, everything else we extracted to the following helper[3]:
This is how the previous tests would look after using the helper:
Notice that we’re passing the probe, the check, the number of probes and the sleep time between probes to the AsyncTestHelpers::assertWithPolling
function.
Conclusions.
We showed an example in Php of an approach to test asynchronous code described by Steve Freeman and Nat Pryce in their Growing Object-Oriented Software, Guided by Tests book. This approach avoids flickering test and produces much faster test suites than using a fixed timeout. We also showed how we abstracted this approach by extracting a helper function that we are reusing in our code.
We hope you’ve found this approach interesting. If you want to learn more about this and several other techniques to effectively test asynchronous code, have a look at the wonderful Growing Object-Oriented Software, Guided by Tests book[4].
Acknowledgements.
Thanks to my Codesai colleagues for reading the initial drafts and giving me feedback and to Chrisy Totty for the lovely cat picture.
Notes.
Some time ago we developed some helpers using the capturing notifications strategy to test asynchronous ClojureScript code that was using core.async channels. Have a look at, for instance, the
expect-async-message
assertion helper in which we use core.async/alts!
and core.async/timeout
to implement this behaviour. The core.async/alts!
function selects the first channel that responds. If that channel is the one the test code was observing we assert that the received message is what we expected. If the channel that responds first is the one generated by core.async/timeout
we fail the test. We mentioned these async-test-tools
in previous post: Testing Om components with cljs-react-test.
References.
-
Growing Object-Oriented Software, Guided by Tests, Steve Freeman and Nat Pryce (chapter 27: Testing Asynchronous Code)
Thursday, October 1, 2020
Books I read (January - September 2020)
- Waltzing with Bears: Managing Risk on Software Projects, Tom DeMarco, Timothy R. Lister
- An Armenian Sketchbook (Добро вам!), Vasily Grossman
- La flor púrpura, Chimamanda Ngozi Adichie
- El día 3, Miguel Á. Giner Bou, Cristina Durán, Laura Ballester
- A Practical Guide to Testing in DevOps, Katrina Clokie
- La espada de Damocles (Finstere Zeiten: Zur Krise in Griechenland), Petros Márkaris
- The Phoenix Project: A Novel About IT, DevOps, and Helping Your Business Win, Gene Kim, Kevin Behr, George Spafford
- Bartleby, el escribiente (Bartleby, the Scrivener: A Story of Wall Street), Herman Melville
- Señora de rojo sobre fondo gris, Miguel Delibes
- Neverwhere, Neil Gaiman
February
- Personal Kanban: Mapping Work, Navigating Life, Jim Benson, Tonianne DeMaria Barry
- The Art of Peace, Morihei Ueshiba
- Theory of Constraints, Eliyahu M. Goldratt
- Johnny Cash: I See a Darkness, Reinhard Kleist
March
- The Amazing Adventures of Kavalier and Clay, Michael Chabon
- Vampir, Joann Sfar (2nd time)
- Lean Software Development: An Agile Toolkit, Mary Poppendieck, Tom Poppendieck
- Dune, Frank Herbert
- Stoner, John Williams
April
- The Wanderer, Fritz Leiber
- Dune Messiah, Frank Herbert
- Bloodchild, Octavia E. Butler
- Children of Dune, Frank Herbert
May
- Agile Coaching, Rachel Davies, Liz Sedley
- Guía de la buena comunicación, Gerardo Sánchez Lozano
- Go Tell It on the Mountain, James Baldwin.
- Ikigai: The Japanese secret to a long and happy life (audiobook), Héctor García, Francesc Miralles
- Yes to Life: In Spite of Everything, Viktor E. Frankl
June
- Fooled by Randomness: The Hidden Role of Chance in Life and in the Markets Rate (audiobook), Nassim Nicholas Taleb
- A Princess of Mars (audiobook), Edgar Rice Burroughs
- Good Omens: The Nice and Accurate Prophecies of Agnes Nutter, Witch (audiobook), Terry Pratchett, Neil Gaiman
- God Emperor of Dune, Frank Herbert
- Ironmind: Stronger Minds, Stronger Bodies: Stronger Minds, Stronger Bodies, Randall J. Strossen
- Man's Search for Meaning (audiobook), Viktor E. Frankl (2nd time)
- Heretics of Dune, Frank Herbert
- Chapterhouse: Dune, Frank Herbert
July
- Moonglow, Michael Chabon
- Managing Technical Debt: Reducing Friction in Software Development, Philippe Kruchten, Robert Nord, Ipek Ozkaya
- Alone in Berlin (Jeder stirbt für sich allein), Hans Fallada
- Building Maintainable Software, Java Edition, Joost Visser
- The Art of Taking Action: Lessons from Japanese Psychology, Gregg Krech
- The Cat's Table, Michael Ondaatje
- A solas, Silvia Congost
- Starship Troopers, Robert A. Heinlein
August
- Medio sol amarillo (Half of a Yellow Sun), Chimamanda Ngozi Adichie
- The Lady Astronaut of Mars, Mary Robinette Kowal
- How to Be a Stoic: Using Ancient Philosophy to Live a Modern Life (audiobook), Massimo Pigliucci
- Flowers for Algernon, Daniel Keyes
- Una partida de ajedrez, Stefan Zweig
- A Country Doctor's Notebook (Записки юного врача), Mikhail Bulgakov
- Being Wrong: Adventures in the Margin of Error, Kathryn Schulz
- Play It as It Lays, Joan Didion
- Panza de burro, Andrea Abreu
- The Power, Naomi Alderman
September
- I Have No Mouth, and I Must Scream: Stories, "I Have No Mouth, and I Must Scream", “Big Sam Was My Friend”, “Eyes of Dust”, “World of the Myth”, “Lonelyache”, “Delusion for a Dragon Slayer”, and “Pretty Maggie Moneyeyes”, Harlan Ellison
- Functional-Light JavaScript: Pragmatic, Balanced FP in JavaScript, Kyle Simpson
- Professor Frisby's Mostly Adequate Guide to Functional Programming, Brian Lonsdorf
- Enchiridion (audiobook), Epictetus
Monday, August 31, 2020
Books I read (January - August 2020)
- Waltzing with Bears: Managing Risk on Software Projects, Tom DeMarco, Timothy R. Lister
- An Armenian Sketchbook (Добро вам!), Vasily Grossman
- La flor púrpura, Chimamanda Ngozi Adichie
- El día 3, Miguel Á. Giner Bou, Cristina Durán, Laura Ballester
- A Practical Guide to Testing in DevOps, Katrina Clokie
- La espada de Damocles (Finstere Zeiten: Zur Krise in Griechenland), Petros Márkaris
- The Phoenix Project: A Novel About IT, DevOps, and Helping Your Business Win, Gene Kim, Kevin Behr, George Spafford
- Bartleby, el escribiente (Bartleby, the Scrivener: A Story of Wall Street), Herman Melville
- Señora de rojo sobre fondo gris, Miguel Delibes
- Neverwhere, Neil Gaiman
February
- Personal Kanban: Mapping Work, Navigating Life, Jim Benson, Tonianne DeMaria Barry
- The Art of Peace, Morihei Ueshiba
- Theory of Constraints, Eliyahu M. Goldratt
- Johnny Cash: I See a Darkness, Reinhard Kleist
March
- The Amazing Adventures of Kavalier and Clay, Michael Chabon
- Vampir, Joann Sfar (2nd time)
- Lean Software Development: An Agile Toolkit, Mary Poppendieck, Tom Poppendieck
- Dune, Frank Herbert
- Stoner, John Williams
April
- The Wanderer, Fritz Leiber
- Dune Messiah, Frank Herbert
- Bloodchild, Octavia E. Butler
- Children of Dune, Frank Herbert
May
- Agile Coaching, Rachel Davies, Liz Sedley
- Guía de la buena comunicación, Gerardo Sánchez Lozano
- Go Tell It on the Mountain, James Baldwin.
- Ikigai: The Japanese secret to a long and happy life (audiobook), Héctor García, Francesc Miralles
- Yes to Life: In Spite of Everything, Viktor E. Frankl
June
- Fooled by Randomness: The Hidden Role of Chance in Life and in the Markets Rate (audiobook), Nassim Nicholas Taleb
- A Princess of Mars (audiobook), Edgar Rice Burroughs
- Good Omens: The Nice and Accurate Prophecies of Agnes Nutter, Witch (audiobook), Terry Pratchett, Neil Gaiman
- God Emperor of Dune, Frank Herbert
- Ironmind: Stronger Minds, Stronger Bodies: Stronger Minds, Stronger Bodies, Randall J. Strossen
- Man's Search for Meaning (audiobook), Viktor E. Frankl (2nd time)
- Heretics of Dune, Frank Herbert
- Chapterhouse: Dune, Frank Herbert
July
- Moonglow, Michael Chabon
- Managing Technical Debt: Reducing Friction in Software Development, Philippe Kruchten, Robert Nord, Ipek Ozkaya
- Alone in Berlin (Jeder stirbt für sich allein), Hans Fallada
- Building Maintainable Software, Java Edition, Joost Visser
- The Art of Taking Action: Lessons from Japanese Psychology, Gregg Krech
- The Cat's Table, Michael Ondaatje
- A solas, Silvia Congost
- Starship Troopers, Robert A. Heinlein
August
- Medio sol amarillo (Half of a Yellow Sun), Chimamanda Ngozi Adichie
- The Lady Astronaut of Mars, Mary Robinette Kowal
- How to Be a Stoic: Using Ancient Philosophy to Live a Modern Life (audiobook), Massimo Pigliucci
- Flowers for Algernon, Daniel Keyes
- Una partida de ajedrez, Stefan Zweig
- A Country Doctor's Notebook (Записки юного врача), Mikhail Bulgakov
- Being Wrong: Adventures in the Margin of Error, Kathryn Schulz
- Play It as It Lays, Joan Didion
- Panza de burro, Andrea Abreu
- The Power, Naomi Alderman
Saturday, August 22, 2020
Interesting Podcast: "The Most Important Thing You Will Ever Learn About Lifting Weights"
Interesting Interview: "The Evolution of the Self"
Interesting Interview: "Seeking Out Disagreement"
Interesting Talk: "How to Do Nothing: Resisting The Attention Economy"
Interesting Talk: "Functional programming patterns for the non-mathematician"
Interesting Talk: "Being Feynman's Curious Sister"
Interesting Conversation: "The Enchiridion"
Thursday, August 6, 2020
Interesting Documentary film: "Seinfeld: Running with the Egg"
Interesting Talk: "Better Living Through Stoicism"
Interesting Conversation: "The pros & cons on Stoicism"
Interesting Podcast: "The Aztecs - A Clash of Worlds"
Interesting Talk: "How Buddhist is Stoicism?"
Interesting Talk: "<<Everything happens for a reason>> -- and other lies I've loved"
Friday, July 31, 2020
Books I read (January - July 2020)
- Waltzing with Bears: Managing Risk on Software Projects, Tom DeMarco, Timothy R. Lister
- An Armenian Sketchbook (Добро вам!), Vasily Grossman
- La flor púrpura, Chimamanda Ngozi Adichie
- El día 3, Miguel Á. Giner Bou, Cristina Durán, Laura Ballester
- A Practical Guide to Testing in DevOps, Katrina Clokie
- La espada de Damocles (Finstere Zeiten: Zur Krise in Griechenland), Petros Márkaris
- The Phoenix Project: A Novel About IT, DevOps, and Helping Your Business Win, Gene Kim, Kevin Behr, George Spafford
- Bartleby, el escribiente (Bartleby, the Scrivener: A Story of Wall Street), Herman Melville
- Señora de rojo sobre fondo gris, Miguel Delibes
- Neverwhere, Neil Gaiman
February
- Personal Kanban: Mapping Work, Navigating Life, Jim Benson, Tonianne DeMaria Barry
- The Art of Peace, Morihei Ueshiba
- Theory of Constraints, Eliyahu M. Goldratt
- Johnny Cash: I See a Darkness, Reinhard Kleist
March
- The Amazing Adventures of Kavalier and Clay, Michael Chabon
- Vampir, Joann Sfar (2nd time)
- Lean Software Development: An Agile Toolkit, Mary Poppendieck, Tom Poppendieck
- Dune, Frank Herbert
- Stoner, John Williams
April
- The Wanderer, Fritz Leiber
- Dune Messiah, Frank Herbert
- Bloodchild, Octavia E. Butler
- Children of Dune, Frank Herbert
May
- Agile Coaching, Rachel Davies, Liz Sedley
- Guía de la buena comunicación, Gerardo Sánchez Lozano
- Go Tell It on the Mountain, James Baldwin.
- Ikigai: The Japanese secret to a long and happy life (audiobook), Héctor García, Francesc Miralles
- Yes to Life: In Spite of Everything, Viktor E. Frankl
June
- Fooled by Randomness: The Hidden Role of Chance in Life and in the Markets Rate (audiobook), Nassim Nicholas Taleb
- A Princess of Mars (audiobook), Edgar Rice Burroughs
- Good Omens: The Nice and Accurate Prophecies of Agnes Nutter, Witch (audiobook), Terry Pratchett, Neil Gaiman
- God Emperor of Dune, Frank Herbert
- Ironmind: Stronger Minds, Stronger Bodies: Stronger Minds, Stronger Bodies, Randall J. Strossen
- Man's Search for Meaning (audiobook), Viktor E. Frankl (2nd time)
- Heretics of Dune, Frank Herbert
- Chapterhouse: Dune, Frank Herbert
July
- Moonglow, Michael Chabon
- Managing Technical Debt: Reducing Friction in Software Development, Philippe Kruchten, Robert Nord, Ipek Ozkaya
- Alone in Berlin (Jeder stirbt für sich allein), Hans Fallada
- Building Maintainable Software, Java Edition, Joost Visser
- The Art of Taking Action: Lessons from Japanese Psychology, Gregg Krech
- The Cat's Table, Michael Ondaatje
- A solas, Silvia Congost
- Starship Troopers, Robert A. Heinlein
Wednesday, July 29, 2020
Interesting Talk: "Stoicism Ancient and Modern"
Interesting Talk: "Stoicism, Mindfulness, and Cognitive Therapy"
Interesting Talk: "Deep Thinking"
Interesting Talk: "Cognitive Behavioral Tools"
Friday, July 24, 2020
Interesting Talk: "Cognitive Behavioural Therapy (CBT) for Anxiety"
Interesting Talk: "History’s Hidden Networks"
Interesting Talk: "The surprising science of alpha males"
Interesting Podcast: "Byzantium - Last of the Romans"
Wednesday, July 22, 2020
Interesting Talk: "Getting to Yes with Yourself"
Interesting Talk: "Reinventing Yourself"
Interesting Talk: "Functional Programming in 40 Minutes"
Interesting Talk: "How to Fall in Love with Anyone"
Interesting Talk: "Conversation on Modern Romance"
Interesting Conversation: " A Vision for Europe 2020"
Interesting Interview: "Talking to My Daughter About the Economy"
Monday, July 13, 2020
Interesting Talk: "The Forgotten Art of Structured Programming"
Sunday, July 12, 2020
Interesting Talk: "The Best OO Language is a Functional One"
Saturday, July 11, 2020
Interesting Conversation: "Valeria Golino and Yanis Varoufakis: Another Now"
Interesting Talk: "Abordar la emergencia civilizatoria tras el Covid-19: retos y aprendizajes"
Interesting Conversation: "Richard D. Wolff and Yanis Varoufakis: Another Now"
Thursday, July 9, 2020
Interesting Talk: "The Science of Great Relationships"
Interesting Talk: "And the Weak Suffer What They Must?"
Interesting Talk: "Mastering The Art of Crucial Conversations"
Interesting Podcast: "The Khmer Empire"
Interesting Talk: "Redefining Economic Value"
Interesting Podcast: "Deescalating Hostile Situations"
Interesting Podcast: "China's Han Dynasty - The First Empire in Flames"
Saturday, July 4, 2020
Interesting Talk: "From Bacteria to Bach and Back: The Evolution of Minds"
Interesting Documentary film: "One Voice in the Cosmic Fugue, Cosmos (2)"
Interesting Documentary film: "The Shores of the Cosmic Ocean, Cosmos (1)"
Thursday, July 2, 2020
Interesting Podcast: "Back Pain and Back Strength"
Interesting Talk: "Tools To Transform Our Thinking"
Interesting Interview: "The myths we need to survive"
Interesting Talk: "Software Development in 100 Years Time & Continuous Delivery"
Interesting Podcast: "The Songhai Empire - Africa's Age of Gold"
Tuesday, June 30, 2020
Books I read (January - June 2020)
- Waltzing with Bears: Managing Risk on Software Projects, Tom DeMarco, Timothy R. Lister
- An Armenian Sketchbook (Добро вам!), Vasily Grossman
- La flor púrpura, Chimamanda Ngozi Adichie
- El día 3, Miguel Á. Giner Bou, Cristina Durán, Laura Ballester
- A Practical Guide to Testing in DevOps, Katrina Clokie
- La espada de Damocles (Finstere Zeiten: Zur Krise in Griechenland), Petros Márkaris
- The Phoenix Project: A Novel About IT, DevOps, and Helping Your Business Win, Gene Kim, Kevin Behr, George Spafford
- Bartleby, el escribiente (Bartleby, the Scrivener: A Story of Wall Street), Herman Melville
- Señora de rojo sobre fondo gris, Miguel Delibes
- Neverwhere, Neil Gaiman
February
- Personal Kanban: Mapping Work, Navigating Life, Jim Benson, Tonianne DeMaria Barry
- The Art of Peace, Morihei Ueshiba
- Theory of Constraints, Eliyahu M. Goldratt
- Johnny Cash: I See a Darkness, Reinhard Kleist
March
- The Amazing Adventures of Kavalier and Clay, Michael Chabon
- Vampir, Joann Sfar (2nd time)
- Lean Software Development: An Agile Toolkit, Mary Poppendieck, Tom Poppendieck
- Dune, Frank Herbert
- Stoner, John Williams
April
- The Wanderer, Fritz Leiber
- Dune Messiah, Frank Herbert
- Bloodchild, Octavia E. Butler
- Children of Dune, Frank Herbert
May
- Agile Coaching, Rachel Davies, Liz Sedley
- Guía de la buena comunicación, Gerardo Sánchez Lozano
- Go Tell It on the Mountain, James Baldwin.
- Ikigai: The Japanese secret to a long and happy life (audiobook), Héctor García, Francesc Miralles
- Yes to Life: In Spite of Everything, Viktor E. Frankl
June
- Fooled by Randomness: The Hidden Role of Chance in Life and in the Markets Rate (audiobook), Nassim Nicholas Taleb
- A Princess of Mars (audiobook), Edgar Rice Burroughs
- Good Omens: The Nice and Accurate Prophecies of Agnes Nutter, Witch (audiobook), Terry Pratchett, Neil Gaiman
- God Emperor of Dune, Frank Herbert
- Ironmind: Stronger Minds, Stronger Bodies: Stronger Minds, Stronger Bodies, Randall J. Strossen
- Man's Search for Meaning (audiobook), Viktor E. Frankl (2nd time)
- Heretics of Dune, Frank Herbert
- Chapterhouse: Dune, Frank Herbert
Friday, June 26, 2020
MOOCs: Managing Your Mental Health During COVID-19
I would like to thank Coursera and Steve Joordens for this great course!
Interesting Talk: "Artisans and Apprentices"
Interesting Podcast: "The Sumerians - Fall of the First Cities"
Interesting Talk: "Why Zebras Don't Get Ulcers: Stress and Health"
Interesting Podcast: "The Greenland Vikings"
Interesting Talk: "Alchemy and the Art of Software Development"
Interesting Podcast: "The Bronze Age Collapse - Mediterranean Apocalypse"
Monday, June 22, 2020
Interesting Interview: "History from A Pattern Language to the Nature of Order"
Saturday, June 20, 2020
Interesting Talk: "Perform Your Best Under Stress"
Wednesday, June 17, 2020
Interesting Podcast: "Facing Your Fears"
Interesting Podcast: "Give Yourself a Break"
Interesting Podcast: "Step Away from Anxiety"
Interesting Podcast: "How did the Norse & the Sámi Interact?"
Interesting Documentary film: "How The Celts Saved Britain Documentary (and II)"
Interesting Documentary film: "How The Celts Saved Britain Documentary (I)"
Interesting Podcast: "The Perfect Problem: Learning to Be Kind To Yourself When You Fail"
Thursday, June 11, 2020
The value of caring
Introduction
We’d like to tell you about a narrative that has been very useful for us in the coaching work we have been doing with several teams during the last year.
Origin
It all started during a consultancy work that Joan Valduvieco and I did at the beginning of 2019 at Trovit. José Carlos Gil and Edu Mateu had brought us to help Trovit’s B2B team. We spent a week with the team asking questions, observing their work and doing some group dynamics to try to understand how we might help them.
After that week of “field work” we had gathered a ton of notes, graphs and insights that we needed to put in order and analyze. This is always a difficult task because it is about analyzing a sociotechnical system (team, knowledge, technology, existing code, organization, pressure, changes,…) which is a complex system in constant flux. In a way, you have to accept that this is something you can’t wholly understand, and even less in a short period of time.
Having that in mind, we tried to do our best to get a first approximation by representing the different dynamics and processes we had observed in several causal loop diagrams. This work helped us clarify our minds and highlight how habits, knowledge, beliefs, culture and practices were creating vicious cycles, (related to some positive feedback loops in the causal loop diagram[1]), that were amplifying and preserving destructive effects for the team and its software which made their system less habitable and sustainable, and created inefficiencies and loss of value.
After that we started to think about strategies that might break those vicious cycles, either by reducing the effect of some node (a problematic habit, practice or belief), by removing an interaction between nodes in a positive loop, or introducing negative feedback in the system (new practices and habits) to stabilize it.
Donella H. Meadows in her book Thinking in Systems: A Primer talks about different types of leverage points which are places within a complex system where you can try to apply what we call change levers to make the system evolve from its current dynamics into another that might be more interesting for the team.
We detected several change levers that might be applied to the system at different leverage points to improve the sustainability of the system, such as, “Improving Technical Skills”, “Knowledge Diffusion”, “Knowledge Crystallization”, “Changing Habits”, “All Team Product Owning” or “Remote First”[2].
All of them attacked vicious cycles that were entrenched in the team’s dynamics, and were valuable in themselves, but we were not sure that they would be enough to change the system’s current dynamics. Something that we observed during our field work was that the team was very skeptical about the probabilities of success of any initiative to improve its situation. They had gone through several failed attempts of “Agile” transformation before, and this has left them in a kind of state of learned helplessness. Why had those previous attempts failed? Would ours succeed using our change levers?
We started to realize that there was a deeper force at play that was exacerbating the rest of the problems and would reduce the effect of any of the other change levers. We realized that they would be useless unless the team had enough slack and company support to apply them. The deeper and stronger force that was inhibiting the possibility of having that slack and support was the very conception of what value meant for the company, it was a cultural problem.
We then came up with a new change lever: “Redefinition of Value”. This was the most powerful change lever of all the ones we had detected because it was a cultural change[3], and it would increase the probabilities of success of all other change levers. Being a cultural change also made it the most difficult to apply.
Redefinition of Value
What was this “Redefinition of Value” change lever about?
The culture of the team was understanding value only as producing features for their clients as quickly as possible. This definition of value only includes certain kinds of tasks, the ones that directly produce features, but excludes many tasks that don’t directly produce features, but that are necessary for the sustainability of the system (the business and team) itself. The first kind of work is called productive work and the second kind is called caring work[4].
Believing that only one type of work has value, (productive work), and then focusing only on that type of work is an extractive micro-optimization that might end destabilizing the system[5].
The redefinition of value we proposed was that not only producing features for the client as quickly as possible is valuable, that there is also value in keeping the sustainability of the business and team. Aside from working on productive tasks, you need to devote energy and time to work on caring tasks which are concerned with keeping the health of the ecosystem composed of the code, the team and the client, so that it can continue evolving, being habitable for the team and producing value. We think that this kind of work (caring work) has value and is strategic for a company. If you think about it, at the bottom, this is about seeing the team as the real product and establishing a healthier and more durable relationship with clients.
This idea of caring work comes from economic studies from a gender perspective. In feminist economics caring work is defined as, “those occupations that provide services that help people develop their capabilities, or the ability to pursue the aspects of their lives that they value” or “necessary occupations and care to sustain life and human survival”.
We thought that for this redefinition of value to be successful, it needed to be stated very clearly to the team from above. This clarity is crucial to avoid the developers having to solve the conflicts that arise when the value of caring tasks is not clear. In those cases, it’s often caring work which gets neglected.
Those conflicts are actually strategic and, as such, they should be resolved at the right level so that the team receives a clear message that gives them focus, and the peace of mind that they are always working in something that is really valued by the company.
In many companies the value of caring only appears in company statements (corporate language), but it’s not part of the real culture, the real system of values of the company. This situation creates a kind of doublespeak that might be very harmful. A way to avoid that might be putting your money where your mouth is.
So with all these ingredients we cooked a presentation for the team lead, the CTO and the CPO of the company[6], to tell them the strategy we would like to follow, the cultural change involved in the redefinition of value that we thought necessary and how we thought that the possible conflicts between the two types of work should be resolved at their level. They listened to us and decided to try. They were very brave and this decision enabled a wonderful change in the team we started to work with[7]. The success of this experiment made it possible for other teams to start experimenting with this redefinition of value as well.
Is this not the metaphor of technical debt in a different guise?[8]
We think that the narrative of caring work, it’s not equivalent to technical debt.
The technical debt metaphor has evolved a lot from the concept that Ward Cunningham originally coined. With time the metaphor was extended to cover more than what he initially meant[9]. This extended use of the metaphor has been criticized by some software practitioners[10]. Leaving this debate aside, let’s focus on how most people currently understand the technical debt metaphor:
“Design or implementation constructs that are expedient in the short term but that set up a technical context that can make a future change more costly or impossible. Technical debt is a contingent liability whose impact is limited to internal systems qualities - primarily, but not only, maintainability and evolvability.” from Managing Technical Debt: Reducing Friction in Software Development
Technical debt describes technical problems that cause friction in software development and how to manage them.
On the other hand, the caring work narrative addresses the wider concern of sustainability in a software system, considering all its aspects (social, economic and technical), and how both productive and caring work are key to keep a sustainable system. We think that makes the caring work narrative a wider concept than technical debt.
This narrative has created a cultural shift that has allowed us not only to manage technical debt better, but also to create room for activities directed to prevent technical debt, empower the team, amplify its knowledge, attract talent, etc. We think that considering caring work as valuable as productive work placed us in a plane of dialogue which was more constructive than the financial metaphor behind technical debt.
How are we applying it at the moment?
Applying the caring work narrative depends highly on the context of each company. Please, do not take this as a “a recipe for applying caring work” or “the way to apply caring work”. What is important is to understand the concept, then you will have to adapt it to your own context.
In the teams we coach we are using something called caring tasks (descriptions of caring work) along with a variation of the concerns mechanism[11] and devoting percentages of time in every iteration to work on caring tasks. The developers are the ones that decide which caring work is needed. These decisions are highly contextual and they involve trade offs related to asymmetries initially found in each team and in their evolution. There are small variations in each team, and the way we apply them in each team has evolved over time. You can listen about some of those variations in the two podcasts that The Big Branch Theory Podcast will devote to this topic.
We plan to write in the near future another post about how we are using the concerns mechanism in the context of caring work.
Conclusions
We have been using the redefinition of value given by the caring work for more than a year now. Its success in the initial team made it possible for other teams to start experimenting with it as well. Using it in new teams has taught us many things and we have introduced local variations to adapt the idea to the realities of the new teams and their coaches.
So far, it’s working for us well and we feel that it has helped us in some aspects in which using the technical debt metaphor is difficult like, for example, improving processes or owning the product.
Some of the teams worked only on legacy systems, and other teams worked on both greenfield and legacy systems (all the legacy systems had, and still have, a lot of technical debt).
We think it is important to consider that the teams we have been collaborating with were in a context of extraction[12] in which there is already a lot of value to protect.
Due to the coronavirus crisis some of the teams have started to work on an exploration context. This is a challenge and we wonder how the caring work narrative evolves in this context and a scarcity scenario.
To finish we’d like to add a quote from Lakoff[13]:
“New metaphors are capable of creating new understandings and, therefore, new realities”
We think that the caring work narrative might help create a reality in which both productive and caring work are valued and more sustainable software systems are more likely.
Acknowledgements
Thanks to Joan Valduvieco, Beatriz Martín and Vanesa Rodríguez for all the stimulating conversations that lead to the idea of applying the narrative of caring work in software development.
Thanks to José Carlos Gil and Edu Mateu for inviting us to work with Lifull Connect. It has been a great symbiosis so far.
Thanks to Marc Sturlese and Hernán Castagnola for daring to try.
Thanks to Lifull’s B2B and B2C teams and all the Codesai colleagues that have worked with them, for all the effort and great work to take advantage of the great opportunity that caring tasks created.
Finally, thanks to my Codesai colleagues and to Rachel M. Carmena for reading the initial drafts and giving me feedback.
Notes
[1] Positive in this context does not mean something good. The feedback is positive because it makes the magnitude of the perturbation increase (it positively retrofeeds it).
[2] Those were the names we used when we presented what we have learned during the consultancy.
[3] In systems thinking a leverage point is a place within a complex system (a corporation, an economy, a living body, a city, an ecosystem) where a shift can be applied to produce changes in the whole system behavior. It would be a low leverage point if a small shift produces a small behavioral change. It’s a high leverage point if a small shoif causes a large behavioral change. According to Donella H. Meadows the most effective place to intervene a system is:
“The mindset or paradigm out of which the system — its goals, power structure, rules, its culture — arises”.
As you can imagine this is the most difficult thing to change as well. To know more read Leverage Points: Places to Intervene in a System.
[4] Also known as reproductive work. This idea comes from a gender perspective of economics. You can learn more about it reading the Care work and Feminist economics articles in Wikipedia.
[5] Sadly we observe this phenomena at all scales: a business, a relationship, an ecosystem, the planet…
[6] Edu Mateu, Marc Sturlese and Hernán Castagnola were then the B2B team lead, the CTO and the CPO, respectively.
[7] B2B was the first team we worked with. Fran Reyes and I started coaching them in February 2019 but after a couple of months Antonio de la Torre and Manuel Tordesillas joined us. Thanks to their great work of this team, other teams started using the caring work narrative around 6 month after.
[8] Thanks to Fran Reyes and Alfredo Casado for the interesting discussions about technical debt that helped me write this part.
[9] You can listen Ward Cunningham himself explaining what he actually meant with the technical debt metaphor in this videovideo.
[10] Two examples: A Mess is not a Technical Debt by Robert C. Martin and Bad code isn’t Technical Debt, it’s an unhedged Call Option by Steve Freeman.
[11] The concerns mechanism is described by Xavi Gost in his talk CDD (Desarrollo dirigido por consenso).
[12] To know more watch 3X Explore/Expand/Extrac by Kent Beck or read Kent Beck’s 3X: Explore, Expand, Extract by Antony Marcano and Andy Palmer.
[13] From Metaphors We Live By by George Lakoff and Mark Johnson.
References
Books
-
Slack: Getting Past Burnout, Busywork, and the Myth of Total Efficiency, Tom Demarco
-
Patterns of Software: Tales from the Software Community, Richard P. Gabriel
-
Filters against Folly: How to Survive despite Economists, Ecologists, and the Merely Eloquent, Garrett Hardin
-
Managing Technical Debt: Reducing Friction in Software Development, Philippe Kruchten, Robert Nord, Ipek Ozkaya
Articles
-
Leverage Points: Places to Intervene in a System , Donella H. Meadows
-
Positive feedback (or exacerbating feedback) (Wikipedia)
-
Leverage points places to intervene in a system (Wikipedia)
-
Twelve leverage points (Wikipedia)
-
Care work (Wikipedia)
-
Feminist economics (Wikipedia)
-
System Dynamics (Wikipedia)
-
Causal loop diagram (Wikipedia)
-
Bad code isn’t Technical Debt, it’s an unhedged Call Option, Steve Freeman
-
Kent Beck’s 3X: Explore, Expand, Extract, Antony Marcano, Andy Palmer