Sunday, May 07, 2023

Good talks/podcasts (May 2023 I)


These are the best podcasts/talks I've seen/listened to recently:
  • Artificial Intelligence: Last Week Tonight with John Oliver (John Oliver) [AI] [Duration: 0:27:00] Funny report on the state of artificial intelligence. Presentation for all audiences. Not technical.
  • Prioritizing Technical Debt as If Time & Money Matters. Goto 2022 (Adam Tornhill) [Engineering productivity, Technology Strategy] [Duration: 0:28:00] Adam presents an interesting approach for classifying and tackling technical debt based on analyzing code changes over time, by authors and files, in order to identify hotspots worth investing in.
  • The Difference Between Continuous Delivery & Continuous Deployment (Dave Farley) [Continuous Delivery, Technical Practices, Technology Strategy] [Duration: 0:18:00] In this episode Dave describes the differences between Continuous Delivery and Continuous Deployment: what each one gives you and when Continuous Deployment may not always be the correct answer.
  • The wet codebase (Dan Abramov) [Software Design, Technical Practices] [Duration: 0:25:00] Interesting talk about software design, design principles, and how it's worth understanding them in their context to apply them correctly. It reminded me of this post I wrote about the DRY principle
  • NUMMI (2015) (Frank Langfitt) [Lean, Lean Manufacturing] [Duration: 1:04:00] (⭐⭐⭐⭐⭐) The interesting history of the NUMMI plant and the joint venture between GM & Toyota. A good story to understand some of the lean principles. There is a previous version of the podcast with other interviews at
  • Many More Much Smaller Steps with GeePaw Hill (GeePaw Hill, Chris Lucian, Austin Chadwick) [Evolutionary Design, Lean Software Development, Software Design, Technical Practices, XP] [Duration: 0:39:00] (⭐⭐⭐⭐⭐) Good conversation about GeePaw Hill's software development approach based on taking continuous small safe steps (Many More Much Smaller Steps).
Reminder, All these talks are interesting even just listening to them.


Monday, May 01, 2023

Lean Coffee: Defer Commitment / Postponer decisiones

El pasado lunes  24/04/2023 tuve el placer de poder colaborar en un Lean Coffee sobre uno de los principios Lean que más me interesan y que creo que menos gente pone en práctica: Defer Commitment.

Gracias a todos los participantes creo que quedo una sesión muy interesante y que espero que tenga continuidad en alguna otra sesión futura.

Gracias a todas las comunidades de Software Crafters que quisieron colaborar con la iniciativa:

Aquí tenéis el vídeo:

Aquí teneís un hilo con algunas de las preguntas y respuestas que se dejaron en el panel:

Referencias y Lecturas relacionadas

Sunday, April 23, 2023

Good talks/podcasts (Apr 2023 I)


These are the best podcasts/talks I've seen/listened to recently:
  • Kent Beck On The FIRST Testing Frameworks, TDD, Waterfall & MORE | The Engineering Room Ep. 16 (Kent Beck, Dave Farley) [Agile, Inspirational, XP] [Duration: 1:07:00] In this episode of the Engineering Room, Dave Farley and Kent Beck have a wide-ranging discussion about the return of waterfall development in software, TDD, Software Design and lots of other things along the way.
  • Master Class with Marty Cagan (Marty Cagan) [Inspirational, Product, Product Discovery, Product Leadership, Product Team, leadership] [Duration: 1:21:00] (⭐⭐⭐⭐⭐) A great presentation on skilled product teams and leading product organizations. The questions at the end are also very interesting.
  • High WIP, multi-tasking, etc. (John Cutler) [Lean, WIP] [Duration: 8:37:00] (⭐⭐⭐⭐⭐) Great explanation about the harmful impact of having high work in progress.
  • Don't Mock 3rd Party Code (Dave Farley) [Software Design, Technical Practices, testing] [Duration: 19:55:00] In this episode Dave explains the dangers of mocking third party code, whose evolution and change we have no control over.
  • The Future of Platform Engineering (Kaspar von Grünberg, Ben Ford, Nigel Kersten, Fatih Degirmenci, Ronan Keenan) [Devops, Platform, Platform as a product, Platform engineering] [Duration: 0:37:00] Interesting discussion about Platform Engineering.
  • Software Craftsmanship al descubierto con Mashooq Badar (Mashooq Badar) [Craftmanship, Inspirational, XP] [Duration: 0:31:00] Interesting interview with Mashooq Badar, one of the founders of the craftmanship software movement in London.
Reminder, All these talks are interesting even just listening to them.


Tuesday, April 04, 2023

Thin infrastructure wrappers

Normally, when using architectures that separate infrastructure code from the rest of the application (hexagonal architecture, clean architecture), it is advantageous to create Thin Infrastructure Wrappers. These wrappers allow us to control (and limit) how we use that infrastructure and decouple us from it.

I've been using this approach for over a decade, and it has always worked very well for me. Also, the small cost of creating the wrapper has always been worth it.

Moreover, these wrappers allow us to use them as boundaries with the infrastructure and avoid mocking third-party libraries, which, although sometimes might seem like a good idea, I can say from experience that is a bad decision that couples us with the concrete implementation and makes it harder to apply TDD with the rest of the code.

When we decouple the infrastructure services using a thin wrapper, we can define some Integration tests to validate the implementation and mock/fake the wrapper to implement the rest of the application (instead of mocking the 3ºParty SDK/driver).

Advantages of this approach:

  • Minimal API surface (minimal features of the infrastructure used)
  • Minimal number of slow integration tests
  • Minimized technology-based code spreading through the code base
  • It allows us to create code that is more tailored to the business language, separating us from purely technical concepts
  • Easy to validate new SDK/infrastructure changes
  • Easy to upgrade to new SDK/infrastructure version (including fast security patching)
  • Enable TDD flow even for code that uses/integrate infrastructure services
  • Less tendency to vendor lock-in (as we reduce the coupling with the infrastructure to the minimum)

Sometimes if we need to use most of the concrete infrastructure functionalities and characteristics (performance, scalability, etc), the thin infrastructure wrapper is not so thin, and we need a different approach. But in most cases, this approach has more advantages than disadvantages.

Example / Redis Cache

Imagine that we need to implement a Cache in our system. We analyze different options and decided that a multi-node Redis cluster can do a good job. As we only need a cache and we use lean software development, we try to satisfy only the current needs (Yagni, defer commitment, simplicity, etc). This means that despite Redis having many use cases and functionalities, we limit its use to the minimum number of functionalities necessary to implement the cache. In this case, it would suffice to have: set_key_with_ttl, get_key, remove_key.

So the RedisWrapper (Thin Infrastructure Wrapper) can be defined as:


  • set_key_with_ttl(key, value, ttl)
  • get_key(key): value
  • remove_key(key)

This small piece can be validated easily with a few small integration tests:

  • it_should_return_the_previously_stored_value
  • a _key_should_expire_when_its_ttl_is_over
  • it_does_not_return_a_key_not_previously_stored
  • it_does_not_return_a_removed_key

Having this Thin Wrapper, we can develop with TDD a Cache class using only fast unit tests that validate with test doubles the usage of the RedisWrapper. The rest of our system doesn’t require interacting with Redis directly and will only use the Cache class. 

The important thing, in any case, is that although Redis provides us with many types of data (hashmaps, sets, counters, etc...) and allows us to implement many patterns (distributed locks, leader boards, bloom filters, object persistence, cache), we focus only on what we need now, thus minimizing the surface area to cover. This allows us to only worry about whether the use case we are using still works when a new version exists, which we can quickly validate with our wrapper integration tests.

In some cases, if the wrapper interface makes it easy to implement the use cases we need, we can include the implementation in the wrapper itself and create only one abstraction instead of two. In our example, this would mean that if implementing the cache using our RedisWrapper is straightforward, we could just use one abstraction and implement a RedisCache class instead of two (RedisWrapper and Cache). Of course, this only makes sense when there is little logic to implement.

Example / RabbitMQ

If we have to implement queue-based communications, we can actually divide the use case into two parts: the publisher and the subscriber.

If the RabbitMQ SDK makes it very easy to implement both the publisher and the subscriber use cases, a good option is to create only one class for each use case that includes the wrapper and the minimum logic to create the publisher and the subscriber.

In that case, the interface of the classes could look like this:


  • publish_message(topic, message)


  • subscribe(topic, message_processing_function)

Example / AWS boto

Upon entering TheMotion, the initial team had created the foundations of what would later become the product. It consisted of a pipeline of different applications that generated videos from templates, photos, and other dynamic elements. The system ran on AWS, and the different applications communicated using queues (AWS SQS) and stored images and rendered video parts in AWS S3.

Unfortunately, the initial team did not have the habit of wrapping third-party SDKs, so all applications were filled with calls to boto, the AWS SDK for Python, scattered throughout the code. The result of this approach was:

  • Integration tests that only covered some cases (since many similar cases were scattered throughout the code).
  • Unit tests that were very difficult to understand. They used Moto ( as a library to mock the AWS SDK (boto). The Setup phase of  those tests was infernal since it required many low-level calls.
  • They only covered some cases due to the cost of developing these tests. The same problem that with the integration tests.
  • We had many errors and debugging problems because it was so difficult to control how each developer used the AWS services (different flags, configurations, etc.) was so difficult. Using boto directly gives too many options for inexperienced AWS developers.
  • Updating boto versions was a titanic task, so the library's version was outdated (and was likely insecure).

In summary, it was a technical debt hell that prevented us from progressing with good testing practices and generated a lot of frustration in our day-to-day work.

With this starting point and identifying the lack of infrastructure wrappers as one of the problems of the initial codebase, we carried out a systematic and conscious process to solve the problem.

  1. We identified the uses of boto throughout the application and defined basic use cases (which covered 80% of the cases).
  2. We implemented several wrappers that practically maintained the AWS boto API as it was used in the applications. That is, we created wrappers for publishing messages to SQS and for saving and retrieving objects/files with AWS S3. These initial wrappers were very similar to the boto API but encapsulated sequences of calls that we always repeated (connecting, getting the client, etc.).
  3. With these wrappers and by extending the wrapper API as needed, we gradually replaced direct use of boto with the wrappers. At the same time, we modified and simplified the tests.
  4. During the substitution and adaptation process, we identified every subtle difference in the use of the AWS API, analyzing whether the difference was necessary or simply the result of chance. If it was necessary, we adapted the API of our wrapper. Otherwise, we simply removed and simplified it.
  5. We removed all the old code when all AWS uses pointed to the new wrappers.
  6. As a final step, we simplified the API of the wrappers by adapting them to their use, rather than to how the AWS API is designed.

Certainly, this process, although costly, was fundamental to accelerate the subsequent development of the product and to introduce the practices that, as an XP team, allowed us to maintain sustained speed (Continuous Integration, TDD, TBD, etc.).


SDKs for infrastructure services usually have the following characteristics:

  • They cover all functionalities and use cases of the service/infrastructure.
  • They are designed for general use.
  • Due to the previous reasons, they have an extensive API (a huge potential coupling surface).

On the other hand, in our applications, we need to define what we want from the service and infrastructure very well, minimizing the API to use as much as possible. This way of working allows us to:

  • Minimize coupling
  • Make more reversible the decision of using this concrete infrastructure
  • Facilitate maintenance  (version updates, configuration changes, etc.).

Additionally, as professionals (because we are professionals, aren’t we?), we need to facilitate application testing. :)

In this context, a Thin Wrapper that covers only what we use, is small, and can be easily mocked is a fundamental piece to help us have a decoupled infrastructure.

In summary, this way of working:

  • Allows us to have tight control over which functionalities and API of an infrastructure service we use.
  • Allows for easy and secure updating and changing of that service or driver/SDK version (with the support of integration tests).
  • Allows for development using fast unit tests that mock the wrapper we have developed.

If we don't create these kinds of wrappers, we may encounter an issue where the use of the infrastructure service API spreads across the application. This can result in a loss of control over the specific functionalities that we are using, and eventually make it difficult to implement any changes to the infrastructure or SDK/driver, including version upgrades, which can become an extremely challenging process.

Another problem that arises when we don't develop these wrappers is that we create many complicated unit tests that mock or, worse, do monkey patching of many SDK/driver methods.

In summary, my preferred option is to create a Thin Wrapper to narrow down the parts of the SDK we need and abstract the basic interactions. Then, we would have another class oriented towards business with the necessary abstractions (publishing a message, storing an object, etc.).

As an alternative option, and only if the business need can be implemented with very little logic, we could potentially combine the Thin Wrapper with the business abstraction. However, this should only be done in those cases and assuming there are no other abstractions on that part of the infrastructure.

To ensure adaptability to changes, it is essential to minimize the surface area of the SDK used, keep it under control, and decouple it as much as possible. It's important to note that we have no control over changes to the SDK, as these are determined by third-party entities such as vendors, cloud providers, and communities.


When using this approach, one must be very careful not to fall into some of the common pitfalls:

  • Overcomplicating the abstraction
  • Allowing complex types or other concepts from the SDK to escape the created abstraction (Leaky abstraction)
  • Ending up exposing the entire SDK API "just in case"

References and notes:

In the article we talk about mocks as a generic term, but to clarify, depending on the needs of the test, we should use different types of test doubles (stubs, spies, fakes, mocks, etc.). More info and



The post has been improved based on feedback from:

Thank you very much to all of you

Thursday, March 16, 2023

Lean Software Development: Defer Commitment

Yesterday, I had the pleasure of presenting the talk "Lean Development: Defer Commitment" at the Madridagil offices. 

I'm sharing the slides here in case they can be helpful to anyone.


Thank you very much to Nexthink for being such fantastic hosts.


Related content

Sunday, February 19, 2023

Good talks/podcasts (Feb 2023 I)


These are the best podcasts/talks I've seen/listened to recently:
  • The Well-Balanced Programmer (J.B. Rainsberger) [Engineering Career, Inspirational] [Duration: 0:52:00] Inspiring talk for any developer. JB gives good insights and fundamental career advice for any software development professional.
  • Why we switched to serverless containers (Florian Forster) [Cloud, Developer Productivity, Operations, Serverless] [Duration: 1:08:00] Florian Forster, talked about why they switched to serverless containers. Zitadel has a really interesting workload that is both CPU intensive and latency sensitive.
  • Architecture for Flow with Wardley Mapping, DDD, and Team Topologies (Susanne Kaiser) [DDD, Engineering Culture, Technology Strategy, Wardley maps, team topologies] [Duration: 0:43:00] (⭐⭐⭐⭐⭐) This talk illustrates the concepts, connects the dots between DDD, Wardley mapping and team topologies, and demonstrates how these techniques help to evolve a fictitious legacy system for a fast flow of change.
  • Systems Thinking for Developers (Jessica Kerr) [Inspirational, Mental models] [Duration: 0:55:00] (⭐⭐⭐⭐⭐) Great explanation of how system thinking arises and its basic concepts. System thinking is a fundamental tool to work with/in complex systems such as software systems.
  • Episode 548: Alex Hidalgo on Implementing Service-Level Objectives (Alex Hidalgo) [Devops, Operations] [Duration: 0:48:00] The episode examines how to define error budgets and policies to influence engineering work, how to tell if your project is under or over budget, and how to respond to being over budget, as well as how to derive value from using up excess error budget.
  • #100 - Modern Software Engineering - Dave Farley (Dave Farley) [Continuous Delivery, Engineering Culture, Technical Practices, Technical leadership, Technology Strategy] [Duration: 1:02:00] Dave started by explaining his view on modern software engineering and why it emphasizes on practices for building better software faster. Dave described the foundations of the software engineering discipline and explained the core competencies we need to succeed by becoming experts at both learning and managing complexity. Dave also explained the importance of understanding technology fundamentals, improving software readability, and handling software complexity by managing concurrency and coupling. Towards the end, Dave shared some other tools in the modern software engineering toolkit that include Continuous Delivery.
Reminder, All these talks are interesting even just listening to them.


Saturday, January 28, 2023

Good talks/podcasts (Jan 2023 II)

These are the best podcasts/talks I've seen/listened to recently:
  • "Unembedding" embedded systems with TDD: benefits of going beyond the make-it-work phase (Francisco Climent) [Agile, Technical Practices, XP, tdd, testing] [Duration: 0:52:00] Interesting talk about the benefits of using TDD in embedded systems. The talk is full of useful tips, patterns, and strategies very useful in both embedded and non-embedded environments. Special mention to how Francisco uses mutation testing in the development process.
  • You Don’t Need CODE OWNERSHIP (Dave Farley) [Continuous Delivery] [Duration: 0:18:00] (⭐⭐⭐⭐⭐) Great explanation about Continous Integration, Continuous Delivery and some strategies that allow to work in small safe steps (Feature Flags, Branch by Abstraction and Dark Launching).
  • Ruby Conf 12 - Boundaries (Gary Bernhardt) [Functional, OOP, Software Design] [Duration: 0:45:00] interesting design proposal combining a functional core (without mutations) wrapped by an imperative object oriented shell.
  • How to become 37.78 times better at anything | Atomic Habits summary (James Clear) [Inspirational] [Duration: 0:28:00]
  • Create Web APIs with ASP.NET Core Using Outside In TDD (Pedro Moreira Santos) [Technical Practices, XP, testing] [Duration: 0:50:00] Pedro describes what his workflow usually is. Very good insights on Testing, boundaries, TDD. Very interesting.
  • Critical Program Reading (1975) - 16mm Film [Quality, Software Design] [Duration: 0:18:00] Interesting document explaining how to improve the maintainability of an application by improving the readability. It is very curious how almost everything that is recommended in this video from 1975 is still perfectly valid.
  • Facilitating Impact Mapping (Gojko Adzic) [Inspirational, Lean Product Management, Product, Product Strategy] [Duration: 0:45:00] Gojko presents early results of an ongoing research on how teams around the world apply impact mapping to speed up time to market and get maximum impact for minimum effort. You'll learn about five important ideas to ensure effective impact mapping sessions.
Reminder, All these talks are interesting, even just listening to them.


Sunday, January 08, 2023

Good talks/podcasts (Jan 2023 I)

These are the best podcasts/talks I've seen/listened to recently:
  • A Philosophical Look at System Dynamics (Donella Meadows) [Systems Thinking] [Duration: 0:53:00] Donella Meadows’ lecture on causal loop diagrams (The most interesting part starts at the 18th minute). Via
  • "Unembedding" embedded systems with TDD: benefits of going beyond the make-it-work phase (Francisco Climent) [Agile, Technical Practices, XP, tdd, testing] [Duration: 0:52:00] Interesting talk about the benefits of using TDD in embedded systems. The talk is full of useful tips, patterns, and strategies very useful in both embedded and non-embedded environments. Special mention to how Francisco uses mutation testing in the development process.
  • You Build It, YOU Run It!' For Continuous Delivery (Dave Farley) [Devops, Engineering Culture] [Duration: 0:17:00] In this episode, Dave Farley describes the practice and implications of holding development teams accountable for their software and how this idea fits with a culture of continuous delivery.
  • Seven shipping principles (David Heinemeier Hansson, Gerhard Lazu) [Company Culture, Engineering Culture, Inspirational, Technical leadership] [Duration: 0:58:00] Very interesting conversation with DHH about various topics related to technology and technology companies. Interesting ideas about the shipping principles, the use of the cloud, and the different tradeoffs depending on the context of each application.
  • How much to invest in platform work (Jean-Michel Lemieux) [Devex, Platform, Platform as a product, Platform teams] [Duration: 0:52:00] Jean-Michel Lemieux, former CTO of Shopify and VP of Engineering at Atlassian, explains how to advocate for investing in platform work, which projects to fund, and what distinguishes a great platform leader.
  • Oredev 2011: Sleeping with the enemy (Gojko Adzic) [Engineering Culture, testing] [Duration: 0:52:00] (⭐⭐⭐⭐⭐) Gojko Adzic describes why independent testing should be a thing of the past. He explains how testers engaging with developers and business users create opportunities to accomplish things they cannot do otherwise.
Reminder, All these talks are interesting even just listening to them.