Lessons learned at CraftConf—the new face of software architecture and making the right decisions

Craft Conference 2019 took place last week in Budapest, and I had a blast. It’s a conference focused on software craftsmanship; with several talks, meetups and discussions taking place over two days in a lovely train museum.

Here are my takeaways from the stories discussed at Craft, divided into three themes: the new face of software architecture and technical leadership, choosing the right layers of abstraction and breaking rigid rules.

I’ll expand on topics discussed in my write-up of Qcon London Conference here.

Role of software architecture in autonomous teams

Last year, the excellent research book on software delivery and organization performance Accelerate was released. One of the most important indicators for higher organizational performance was the presence of empowered, autonomous teams working on the products. These are teams which …

  • have the ability to make large-scale changes to the design of a system without permission from outside the team
  • do not need to perform detailed coordination outside of their team.

Co-author Jez ‘Continuous Delivery’ Humble was present and gave a talk on their research here.

Several talks went into what this means for technical leadership and the role of software architecture in such teams. Because if everyone is empowered to do what they want, what could possibly go wrong 💣? wonders Emily Bache. Can you trust those teams with software architecture decisions?

Software architecture is about making sure the qualities a system should have (these are often referred to as the *-ilities like availability, reliability … ) are present in the product and that making changes to the product remains sustainable over time. Not every quality is compatible with each other or is required at a high level for the product. It’s the technical lead’s responsibility to identify the focus and validate the quality priorities with the business and identify and explain the trade-offs for their context. Next, he or she translates this to design principles for the team to focus on.

There are a lot of design principles / guidelines you can follow, but it’s the tech leads role to explain why the team should choose to focus on these: what happens when they’re not followed, and how do they affect the system’s architecture? That’s what cultivating architecture is about, according to Martin Fowler and Birgitta Böckeler. These teams are loosely coupled, but should be highly aligned on the strategic goals and architecture principles. They aren’t told what to do, but know what’s important for the organization and which sensible defaults apply. Teams can diverge from these sensible defaults, with a substantiated choice. Excellent talk.

Evolutionary Architecture

Architecture in agile teams is not a step done at the start of the project nor should its outcome be limited to diagrams stored somewhere for no one to read ever again. The architecture should evolve in small incremental and business-relevant steps, says Neal Ford.

To ensure your software evolves in the right way, define fitness functions which can validate your software qualities in an objective and automatic manner. Testing libraries such as JDepend or ArchUnit (.NET alternatives exist) allow you to create automated tests for cyclic dependencies, or imports across modules or abstraction boundaries in a disallowed manner and so on. Done right, it means you don’t have to jump to separate run-times (microservices) just to avoid the big ball of mud. Netflix’ Simian Army tests services at run-time and terminates them if they are no longer used or don’t comply. For Performance, you can test your error budget during build or monitor the golden signals. Whatever you do, make sure your fitness functions are measurable and can’t be gamed (like code coverage). The tech leads ensure these are set-up accordingly.

Task list for the new software architect

So to summarize, this is how you might want to write a CV for the new software architect / technical lead …


  • You touch the code and works on fostering a good technical environment (a clean kitchen), with automated tests and fitness functions; measuring and validating that the software evolves in the right way
  • You nurture technical knowledge sharing in the team, with a shared understanding of the architectural principles (and why they apply) which will guide the team’s decisions (as sensible defaults).
  • You link the architectural principles with the product needs and economics; and how you can keep making incremental changes sustained over time.

The right level of abstraction and product focus

So we know the teams require high alignment and having a good environment which fosters the sharing of knowledge and application of good practices. How can we increase the skills of team members and work on the shared understanding of what makes a design decision?

What makes Domain Driven Design still relevant after 15 years, wonders Nick Tune. For Nick, it’s the focus on product discovery and everyone in the team should be involved and contribute to the product ideas. If they’re further removed from the customer problems, he suggests to organize a business quiz regularly for the entire team, which I’ll definitely be doing to drive this home.

There are many design principles like SOLID and the DDD terms and if you follow them blindly at all times, it leads to disaster. This was a principle which came back in several talks; that reusable code is less usable and that you take a loan when you create an abstraction: you owe in performance and you owe in readability across the layer boundaries. Choose wisely. The design principles chosen previously for your team can help to guide decisions, as well as resisting to DRY out your code until the 3rd or 4th copy-paste. You’ll get a better idea of what the real problems and use cases are by then. Don’t do API or test-first design without stakeholders either for this reason, warns Theo Schlossnagle, in order to add simplicity to your complex systems.

As Ash Maurya said, “Life’s too short too build something nobody wants”. Clean code lives in the software craftsmanship world, but even more important is code solving a customer problem.

Llewelyn showed off the Approvals testing library for refactoring untested code. If you need to refactor code which doesn’t have tests, you can use approvals to quickly create tests based on the existing output (and visually confirm the output), so you can verify with your refactoring that you don’t break anything.

Llewelyn and Emily also organized a late night mob programming session, which is a useful practice to work together on a single problem with a team and in doing so share knowledge on how you tackle challenges. It was a lot of fun and we started to apply it this week in my team, starting with half an hour a day. If you want to try it out yourself, Emily offers some tips in her talk mentioned earlier.

Industrialized agile and complex system management

Next to the architecture and craftsmanship challenges there was another element which came back in several talks: the dislike expressed towards ‘industrialized agile’ project management. The main complaints are that the focus on the customer has shifted towards a set of rigid rules, applied without regarding the context of the team. Perhaps some management methodologies from the 90ies (like SCRUM) aren’t always a good fit for every team. Go deeper and see what’s effective for a team combining different ideas, ditch the standard index cards; is what Dan North advises while recounting different stories from his career.

A hilarious comparison was made by Dave Snowden, giving an idea of how you might want to organize a children’s party in a truly SAFe and agile-certification approved way. Complex systems require different approaches, and the Cynefin framework he invented may help you in decision taking.

Unfortunately neither talk is online yet, the talk given by Dan is available here from another conf. I’ll update the links when they come online.

In conclusion

This is what I’m taking away:

  • The lean mindset is alive and well in the craftsmanship community. Yes we all like pretty code, but until it’s live and solving a customer’s real problem — it’s dead code. Abstractions are loans, reusable code is less usable. Be careful. Decide what’s important and communicate the trade-off made.
  • A reminder to emphasize product discovery (where is the customer?) and to cultivate this in the entire team. Going to hold quizzes at regular intervals to test this.
  • Leadership: foster more knowledge sharing and creation. We’re giving mob programming a shot this sprint, 30 mins a day. So far it’s been a lot of fun and insightful for everyone, going through problems in different components and services of the system.
  • There was also an excellent introductory talk on CSS Grid by Bill Odom which won me over and I’ll be trying out in one of my projects. CSS Frameworks like Bootstrap remain useful for components, but you should stop using them for your layout; CSS Grid is much better and widely supported with fallbacks available.

Hope you enjoyed the read! If you want more, my QCon summary of March 2019 is available here. Next I’ll be writing about how to do security design in teams.

Thanks for reading! If you liked this article, you may also like one of the most popular posts: How to make software architecture trade-off decisions or How to get started with Threat Modeling, before you get hacked. or scroll through the history below or on the main page.

Get notified of new posts by subscribing on substack or the RSS feed.