Software Craftsmanship: How to build well crafted software?

In his book The Software Craftsman: Professionalism, Pragmatism, Pride, Sandro Mancuso said « Software Craftsmanship is a long journey to mastery. It’s a mindset where software developers choose to be responsible for their own careers, constantly learning new tools and techniques and constantly bettering themselves. » As a Software Craftsman I wanted to share with you some techniques/practises that really worked well with my teams and that enable to constantly improve code quality and motivate people. In the article, I’ll talk about what it is to be agile, about TDD, BDD, XP (Pair Programming, Mob Programming, …), Continuous Integration / Delivery, Clean Code,…

Shorten the feedback loop

Agile methodologies are all about quick and short feedback loops. The quicker and shorter our feedback loop is, the more agile we can become. S Mancuso.

It’s important when using Agile methodology to reduce the feedback loop. I will describe in this section an example of agile methodology (SCRUM) and how it could be used to shorten the feedback loop.

To start with, it’s important to have short sprints (e.g. 2 weeks). Before starting the sprints, all members of the team (Developers & Business Analysts [BA]) should understand all the subjects (User Stories) for the sprint. By doing so, when starting the sprint with a Planning Game (Planning Poker) people can give a good estimation for each user story. During the planning game, it’s important every developper gives their own estimation for each user story. If for example two developers give 2 very different estimations (for example 2 points vs 5 points), that usually means some of them does not understand what needs to be done. It’s a great opportunity to use pair programming or MOB Programming for user stories like that. Once all user stories are sized, the sprint can start. Each developper should be able to work on any user story they want. For each development it’s very important to use Pair Programming or Code review. If the user story is implemented by one person then another (random) one should do the review and the user story should not be deployed if the review is not OK. During daily meetings, User Stories « pending in Review » should be pointed out and developers should do the reviews (every morning) before working on anything else. By doing so, each User story will be implemented, reviewed, deployed and tested quickly (feedback loop). Once the User Story is reviewed, it should be automatically deployed in tests environment and tested (by BAs or other developers) very quickly.

Before starting a new sprint it’s very important to demonstrate the User Stories of the current sprint in front of all the team and PO/Business (if possible). Also a « Retro » should be done by the team. It’s a great opportunity to point out things that need to be improved. Actions need to be taken for the next sprint for those things. Finally a presentation of the user stories for the next sprint should be done so all the members of the team will be ready for the next planning game.

TDD

Tests Driven Developments practice is a great way to reduce feedback loop and to write good code. The principle is very simple. When implementing a requirement/feature, we should start by writing the test first. Then we can implement the feature and then do the refactoring. The Refactoring part is very important (the most important part as far as I’m concerned) when doing TDD because it enables to make sure that we are using good practices (good naming, small functions/methods, dependency injection, SOLID principles, Hexagonal Architecture to avoid external dependencies and so on).

It’s important to use « baby steps » and write small tests. Write a test for a single feature then implement the feature and refactor. Do the same thing for the next feature. I will write another time a detailed article about TDD with step by step examples. In the meantime there is a great book from Kent Beck Test-Driven Development by Example, which I strongly recommend to read.

Here are some great advantages of using TDD:

  • The first advantage is obviously TDD enables to have code already tested (less bug in Production 🙂 )
  • By using « baby steps » we make sure to handle specific cases (Null inputs, Error handling, …)
  • With TDD there is no over-design (no design up-front!)
  • TDD enables to have a live documentation. Reading the tests classes enable to understand the requirements, features, …
  • TDD is also a « Non Regression Tests » (NRT) tool
  • TDD enables to detect wrong design. When we’re struggling to test a method (for exemple difficulties to Mock external dependencies) it usually means we have design problem, for example:
    • No Dependency Injection
    • No SOLID principles
    • A lot of static classes
    • wrong architecture

BDD

BDD as Behaviour Driven Developments is a practice that encourages collaboration between developers /BAs, POs (Product Owners) and Business people. They elaborate the requirements together by using structured scenarios.

Example of scenario (from Specflow website)

A scenario is a file that describes the requirements. It should be described using a simple syntax (for example by using Specflow or Cucumber frameworks). Once the scenarios are written/validated, they will be used like a « TDD pattern ». First when the scenarios are integrated in the project, the tests (represented by all the scenarios) will fail. Then we should implement the requirements to make the tests Green. And finally do the Refactoring.

Here are some examples of great advantages of BDD:

  • it enables developers and PO/BA/Business to work better together
  • like TDD it enables to have clean code and more importantly, to have working code (since the scenarios are already validated by PO/BA/Business People before the implementation). Indeed the scenarios drive the implementation.
  • it’s a great NRT (Non Regression Tests) tool
  • like TDD it enables to have live documentation (business rules are integrated in the « Code »).

Pair Programming

Pair programming is more a social activity than a technical practice. It enhances the team spirit and brings developers together. S. Mancuso

As a Software Craftsmen, we should always seize the opportunity to share our knowledge (technical & functional) and to learn from others. Pair Programming is a great way of doing that. Many developers are not comfortable doing Pair Programming because they are afraid to expose their own limitations or they might think that others will slow them down.

When pair programming, we always learn from others (new development technique, new framework, keyboard shortcuts,…) We get an immediate feedback on our code and ideas which is really important to shorten the feedback loop. When other developers can’t understand our code/design, this may be because something is wrong about it and it may be an opportunity to reevaluate our own opinion 🙂 Besides a code written by 2 persons is always better than the one written by only one of them. Here is an example of how you can set up Pair Programming in your teams.

  • Pick a user story and ask another developer to join you
  • Start by explaining the topic (even if all the members of the team should understand the purpose of each user story) and what need to be done.
  • Agree on which development technique to use: TDD
  • Start coding (writing tests first, implementing, refactoring) for a specific time (for example 10/15 min). Once the time elapsed, the other developper will continue. Do that until the user story is fully implemented. It’s important to communicate when you’re coding, to explain what you’re going to do and why.
  • Deploy & Test
  • Do the same for another user story but with another developer (it’s very important to pair with every member of the team, specially with new members).

Mob Programming

This is my favorite 🙂 Mob Programming is like Pair Programming but with more people (3 to 5) and for several hours (2/3 hours). Mob Programming is a great way for on-boarding new members of the team and a great way to share knowledge. Here is an example how you can setup a MOB in your teams:

  • During planning game (beginning of the sprint), figure out which user stories you want to do using MOB. For each of them decide which developer is going to be the « Manager » (you can choose another term if you want 🙂 )
  • The job of the « Manager » is to study the user story so at the beginning of the Mob session they can explain to everyone what needs to be done and provide a solution.
  • During the Mob, bring only one computer (with projector)
  • Discuss about the solution provided by the « Manager » and find a better solution if any. Agree on a solution (At this point there is no « Manager » anymore).
  • Like TDD, every one will have to code for a specific time (10/15 min) (stop coding when the time elapses)
  • When someone is coding, it is important that everyone participates (shares their ideas, suggestions, …)
  • Loop until the end of the session
  • At the end of the Mob, if the implementation is not finished, the last person who was coding will continue the development. (Do not forget to ask for review for this case for the extra code added) .
  • Choose a different « Manager » for the next Mob.
  • Try to organise a MOB session on a regular basis.

Code Review

For each user story implemented by a single person, another developer should do the review ASAP. It’s very important because it enables to know wether the code is well written, to share knowledge,…

If the person who did the review has some remarks, the code needs to be fixed ASAP. If there are a lot of remarks may be the 2 developers can pair a little 🙂

Clean Code

It’s good to do Pair Programming, Mob Programming and stuff but before that developers should know the clean code bases.

There is a wonderful book from Robert C. Martin, Clean Code: A Handbook of Agile Software Craftsmanship, that I believe every developer should read.

Here are some examples of « clean code bases »

  • Naming: choose the right names for your classes, Methods, objects,… It’s important to take some time to choose a good name
  • Small functions, classes: « The first rule of functions is that they should be small. The second rule of functions is that they should be smaller than that » Robert C. Martin
  • Comments: we should avoid using comments to describe a variable, a function,.. Choose a good name instead
  • Nested If: here is an article that describes the concept and a possible solution.
  • Avoid « if instructions«  with several And/or: create meaningful boolean function instead.
  • Do ONE thing: Single Responsibility Principle

It’s also important to know the best practices like SOLID, dependency injection, Hexagonal architecture, …

Continuous Integration / Delivery

In order to shorten feedback loop, once a development is committed (after review), the project should be automatically built and the entire tests (at least Unit Tests, NRT and BDD) should be run by Continuous Integration tools (Team City, Jenkins,…). If the build or a test fails then an email should be automatically sent to the developer who wrote the code (only the developer). In this case the developer should fix the build before doing anything else. This should be an emergency. It’s important to have rules like this in order to always have clean code base. For example when working with Git, the master branch (or sprint, or develop or any branch for which different developers are working on) should always be clean (build OK & all tests OK).

It’s also important to have a Continuous Delivery system. For each commit, the development should be automatically deployed to (at least) a DEV Environment (a common environment used by developers to test their developments). The deployment to others tests environments (like UAT) should be easy and quick as well.

Keep Learning

I wanted to finish with the most important. I believe we should always learn new techniques/practices and try them out. A software Craftsman should always be up to date. There are some simple ways to do that.

  • Read books: as far as I’m concerned reading books is the greatest way to learn new techniques/practices (to have a deep understanding)
  • Read tech blogs
  • participate to open sources projects
  • Follow other Craftsmen
  • Attend Meetups, Conferences (like New Crafts, Devoxx,…)
  • Do Code Retreats
  • Do BBL (Brown Bag Lunches) with your teams

Conclusion

First of all, thank you for reading my entire post 🙂 I wanted to share these principles because I strongly believe they enable to build well crafted software. As a Tech Lead, I always try to make sure people I work with constantly try to better themselves. I try to share my knowledge and I always learn form others.

Feel free to share your thoughts 🙂

Une réflexion sur “Software Craftsmanship: How to build well crafted software?

Laisser un commentaire