A couple things generally strike me when I approach a codebase -
Abstraction - will allow code reuse in many parts of an application or difference services.
Decoupling will remove dependencies between blocks of code.
For me, this is a good candidate for refactoring exercise. At the start, it can be difficult to visualize where a meaningful abstraction can happen.
When an application is in a mature state then it will be easier to see where abstraction can add value.
A few signs of bad abstraction;
- code requires maintenance
- code is only used once
- code has a complex configuration
- code requires complex set-up for testing
A great post on this is 'Duplication is far cheaper than the wrong abstraction'.
Decoupling can promote reuse but that is a common misconception that it is the goal.
Decoupling is about making parts of a system independent from one another. There are many good reasons to do this;
- should help to make parts easier to replace
- should promote smaller code sets
- suited to microservices
Decoupling often happens by design, making good choices will help avoid coupling.
Doing things like
- API gateways
- MVC application patterns
These promote the idea of code independence which should also make for maintainable code.