From theory to practice: How Craftsmanship can help you achieve your goals

Imenezzine
The SensioLabs Tech Blog
5 min readOct 11, 2023

--

© Unsplash by La Compagnie Robison

Through this article, I share my experience of my latest mission, where I had the opportunity to explore and practice Craftsmanship methods. Discover with me a practical example of how Craftsmanship can work in a development project.

Before this mission, I was a huge fan (and still am 😜) of this development approach based on code quality. It reminds us of the importance of using good practices to build simple, quality software that can evolve without defacing it too quickly.

An introduction to Software Craftsmanship

Before we get started, here is a short history of software craftsmanship. In 2008, this movement was born when Uncle Bob introduced “craftsmanship over execution” as the fifth value in the Agile manifesto. This manifesto is a set of principles and values designed to improve software development by encouraging collaboration, simplicity, and flexibility. Craftsmanship is first and foremost a state of mind.

Software craftsmanship focuses on:

  • the quality of software development through practices such as TDD, BDD, and the art of refactoring)
  • collaboration by setting up workshops between developers and stakeholders, clarifying business needs, elaborating a common language, etc.
  • the developer’s satisfaction with their work.

This approach is based on a toolbox of methods and best practices that every developer needs to know and apply to create high-quality software. This toolbox includes TDD, BDD, Clean Code, DDD, Legacy Remediation, SOLID principles, etc.

I would like to start by saying that I had the chance to try out all the techniques in the software craftsmanship toolbox, thanks to the company I worked for in my last mission. We had the freedom to choose the method, technology, and architecture we wanted to build our project. We were lucky 😊 as it was a project from scratch with an open-minded team who gave us carte blanche to try out whatever we wanted. So, my colleague Etienne and I explored all the possibilities we could.

My first technical steps in craftsmanship

After the start of the project, we launched into the technical side of things. We installed our favorite Symfony framework ❤ and opted for a hexagonal architecture.

An overview of hexagonal architecture on a symfony project

Why hexagonal architecture?

This architecture was invented by Alistair Cockburn to make our application testable, based on the SOLID principle (dependency inversion (D)), protecting the business domain (independent of the framework) and improving the maintainability and flexibility of the application.

First, we should not jump straight into programming 😅 Before that, we need to explore our domain, understand the project well, identify all our use cases, and set up a common lexicon with the whole team (business and developers). We used a broad selection of ceremonies, such as Event Storming and Example Mapping, to help us understand the context and identify the domain.

Everything was ready to start the first User Story, but a few questions remained: how to proceed? Where to start? How do you prevent oversights and stay focused on solving the problem without getting lost in the details? Our worries, as Kent Beck mentions in “Test Driven Development: By Example,” were productive. It encouraged us to explore our resources, leading to the discovery that the TDD method addressed our concerns.
So, using this method, we started by writing our tests before tackling the code. The aim was to clarify our needs and define the expected behaviors in advance, and this is where we approached the subject of Example Mapping. What is Example Mapping, and why do you need it?💁

Example Mapping demystified

Example Mapping is a workshop in which the development team meets with the product owner. It is the opportunity to talk, exchange ideas, and get a clear understanding of the need, based on practical examples. It is a ceremony that encourages communication and exchange between the technical and business sides.

Once we have covered all the examples relating to the part yet to be developed, it is time to start development. To write our tests, we chose to work with the Behat/Gherkin language, which is readable, easy to write, and modified. We could also have used PHPUnit: it is up to you 😉

Feature: Hotel Room Booking
As a customer
I want to be able to book a room in a hotel
So that I can plan my stay in advance

Scenario: Successful room booking
Given I am on the hotel booking page
When I select the check-in and check-out dates
And I select the number of guests and rooms
And I click on the search button
Then I should see a list of available rooms
And I should be able to select a room and book it
And I should receive a confirmation of my booking

With my colleague Etienne, I spent hours in peer programming with keyboard changes every few minutes (I already miss it 😅). We opted for this collaborative technique because collaboration is an art that every developer needs to learn 😍

When using TDD, development takes place in several iterations. You need to keep in mind that the goal is to write as little code as possible while fulfilling the expected functionality. Here is a diagram with each iteration broken down into three stages: red/green/refactor. This diagram could look familiar to those who read my previous article on TDD vs. TFD.

Test Driven Development illustration

Red: in this phase, we will imagine what we want to develop.

Green: in this phase, we will think about how to pass our test.

Refactor: in this phase, we will improve the code, modifying implementation details without, of course, changing the behavior.

With my colleague, we started with the first tests, stringently applying this technique by writing the minimum code to make our test pass step by step. And I must admit that it was both fun and magical. Every time it is green, I can feel the victory (I’m overdoing it, I know 😆).

Using in-memory programming, we simulated the environment without a real database, collaborating in pairs to develop different parts of the implementation. After two weeks, we merged our work and, within an hour, we had a working application with well-tested minimal code, meeting the requirements perfectly 🚀

Conclusion

This method was our working methodology throughout my mission, and we spread it to all our co-workers on this project.
Using this methodology, I must admit that we were never afraid to refactor our code, improve it, or even add new conditions or features. We were fully confident in what we were doing. We would just modify our test to meet our new needs and try to get it through step by step, and that was all 😍🚀

If you prefer to read my article in French, here is the link to the French version

--

--