First, let’s consider two extremes. An application consisting only of business logic, with BICR=100/0. Its code works only in unit test suites and is not usable by the end users.
On the opposite, there is an application consisting only infrastructure code, with BICR=0/100. This one is also not usable, because it has no business logic.
Therefore real applications always have BICR somewhere in between these two extremes. Intuitively I want to keep BICR as high as possible, because then I have less infrastructure code to maintain, and can deliver more business value. The natural way to achieve this goal is to introduce frameworks into the application. That’s what we are – as developers – actually doing almost automatically, often without thinking much about it. This lack of care and diligence may cause serious problems.
Roll your own and have an illusion of full control
Let’s meet Paul who is a proficient Java developer. Paul learned how JDBC drivers work. He also read about SOLID principles. Just joined a mature project and see the codebase is so ugly. He feels, he can do it much better. Without much thinking, he starts doing refactorings here and there and accidentally rolls his own private framework. Of course, it can also be a conscious decision. Anyway, it is the most spectacular mistake often made. Perhaps it’s rare to roll own DBMS these days, however, dependency injection frameworks or persistence abstractions are not. Writing own frameworks is for sure very exciting task, yet it brings several downsides and risks:
- Usually poor documentation – the authors know their code, so there is no good motivation to write it down, and of course, it’s a waste of time
- Bugs, performance, security and design issues – testing frameworks may be non-trivial task, also small user-base does not help here
- Expensive onboarding as there are no candidates knowing this solution
- Problematic upgrades to newer language versions
Overkill can kill your project
Tom is more experienced than Paul, much more. He’s passionate about most fancy frameworks with all their bells and whistles. Recently, in the project he’s working on he convinced everyone around to use that fantastic foo-bar framework. That leads us to another case called using an inappropriate framework – it may be harder to identify for an inexperienced person than the one above. That’s why it is important to consult, verify and approve design decisions by seasoned developers, otherwise, the risks are:
- Complex and/or expensive architecture (eg. let’s use blockchain)
- Inability to benefit from framework advantages because it does not fit to the problem
- Accidental complexity grows because of glue code required by the framework
In one of the user stories Paul was implementing import from CSV file and to accomplish this task he decided to add csv parsing library to the project. In the next sprint Tom was implementing something similar, however, he was unaware of the existence of that parsing library and had added another one. That’s the third case – using multiple libraries to solve similar problems – this may happen when people working on the project do not share knowledge and/or are not aware of the features provided by libraries being already in use in the project.
Such problems often origin from lack of knowledge. That’s why it is important to:
- Share knowledge across the teammates
- Know the frameworks you use.
- Learn about other popular frameworks that you may use in the future
- Maintain a list of frameworks of first-choice
Stories similar to those above taught me that creating software is most of the time an art of making proper choices. Especially because our decisions often determine next questions we have to answer. There is almost no room for automatic decisions. BICR is one of the tools that help me with that. To use it I do not have to measure the lines of code exactly. It’s totally enough to get an overall feeling about the impact of the framework before taking the decision.