Through the years a bunch of “X”-driven developments/designs have emerged, such as Domain Driven Design, Test Driven Development, Behavior Driven Development etc. These design principles all have their own focus on different parts of development, and what I think is missing is a more higher level, over arching design principle. Therefore I have formulated the “Freedom Driven Design” principle.
The goal of the principle is to enable the creation of quality software by accepting that we can not predict the future and thus should make an effort to have the freedom to adapt to change.
Here is version 0.1 (the numbers in the list do not implicate importance, only reference)
With freedom driven design we should strive to enable the freedoms to
1. Make changes without fear of breakage
2. Make changes with understanding of the effects to the overall software
3. Use the best language for the job at hand
4. Use the platform of my choice, do not get owned by platform vendors
5. Use the development setup that I am most productive with at a location of my choosing
6. Work in team constellations that respect my type of personality
7. Deploy when ever the business wants to
8. To view and fork any of my dependencies, do not get owned by frameworks
9. To change my software when it suits the business and not at the will of any dependency vendor
The current enablers for FDD is Simple languages and designs, Continuous Integration, excellent test coverage, Container technology and a work culture promoting individual freedom.
As a concrete example, lets look at my opinionated toolbox that have the possibility to deliver on these principles. While technologies come and go the toolbox should be updated to state-of-the-art when needed, but the principles should be the guidelines when selecting those tools.
Design (1-2):
Reduce accidental complexity at all cost. Avoid mutable state as much as possible and where you need it keep it isolated at the edge of your application. Have a clear separation of concerns and clear boundaries. Cross boundaries by passing immutable data. Reduce lines of code as much as possible, deleted code is debugged code.
Language (1-3):
In my opinion the toolbox currently need three languages. One “close-to-the-metal” for scenarios when resources are scarce or when performance really is key. (currently C, might become Rust). The second language is our general purpose language for solving your core business logic. Here my current choice for the last 5 years have been Clojure. The simplicity that default immutability, the focus on data and the expressive power of LISP is hard to beat. The last language to be able to wield is a front end oriented language. Right now and for the foreseeable future that will be JavaScript and/or languages that compile to JS. I chose ClojureScript, for the same reasons that I am using Clojure on the back end.
Platform (4-5):
First class support for containers. Not restricted with licensing. Great package management. You should be in control of your update cycle, not any vendor. For me this is currently GNU/Linux, but I would settle for any that are UNIX based. Note however that in some cases your business case is targeting a specific platform, but even in those cases where platform is decided, keep platform freedom in mind when designing. If the application is successful, it will usually have to increase reach to multiple platforms.
Location (5):
People are different and want to work in different settings, use the tools needed to make it work. For me the tools right now are Trello, GitLab/Hub, Slack and voice chat, those tools make my location independent and that works for me.
Co-workers (6):
You should be in control of who you choose to work with. Some people do their best work in isolation some in groups, we are different. And just because you want to do work alone do not imply that you are not capable of cooperation with others. A team of introvert individuals bringing your business closer to your goals is as good as a team of extroverts who cherish the opportunity to mingle in teams. Accept and embrace differences and you will get the most out of your developers.
Deployment pipeline (7):
Automate everything. On every commit, there should be a build produced with a complete test pyramid run, static code analysis, test coverage, style guide analysis and if all pass, the build should be containerized and ready for production deployment at the push of a button. The tools are somewhat stack dependent, but if your stack lack the required tooling, you should really think twice before adopting it.
So this summarize version 0.1 of FDD. Even if you do not agree on the toolbox, there is hopefully some take away from the principles outlined.