There are five attributes that can be used as tools to manage complexity:
- [[Modularity]]
- [[Cohesion]]
- [[Separation of concerns]]
- [[Abstraction]]
- [[Coupling|Loose coupling]]
These attributes are almost universally desirable at some level for software systems, independent of their architecture or tech stack.
## Symptoms of complexity [^fn1]
[^fn1]: [Extracts from A Philosophy of Software Design](https://www.becausetech.rocks/blog/design-philosophy/) by Florian Sauter
1. **Change Amplification**: This basically means that a simple change requires touching many different places in the code.
2. **Cognitive Load**: How much does a developer need to know to properly modify a piece of code?
3. **Unknown unknowns**: When it’s not obvious which parts of the code need to modified to achieve a certain outcome
---
## References
- [[Modern Software Engineering]] by [[David Farley]] ([link to book](https://www.amazon.co.uk/dp/B09GG6XKS4/ref=dp-kindle-redirect?_encoding=UTF8&btkr=1))