This is just a quick post sharing something I was able to figure out after doing some research.
The situation: our application throws exceptions by means of "talking back to the user".
As developer we don't want to be notified about all these exceptions.
They aren't as important as any other exception that should be considered "critical".
Still, we do want to find these exceptions in the logs, because they can sometimes provide valuable feedback about the usability of the system.
If you want to write applications that are maintainable in the long run, you have to decouple from your framework, ORM, HTTP client, etc. because your application will outlive all of them.
Three simple rules
To accomplish framework decoupling you only have to follow these simple rules:
- All services should get all their dependencies and configuration values injected as constructor arguments. When a dependency uses IO, you have to introduce an abstraction for it.
- Other types of objects shouldn't have service responsibilities.
- Contextual information should always be passed as method arguments.
I write about design rules a lot, but I sometimes forget to:
- Mention that these rules can't always be applied,
- Describe when that would be the case, and
- Add examples of situations where the rule really doesn't matter.
The rules should work in most cases, but sometimes need to be "violated".
Which is too strong a word anyway.
When someone points out to me that I violated a rule, I'm like: Wow! I violated the rule? I'm so sorry! Let's fix this immediately.
Whereas in practice it should be more like: Yeah, I know that rule, but it makes more sense to follow that other rule here, because [...].
In other words, pointing out that a certain rule has been violated should not be a sufficient reason to adhere to that rule.
My favorite example is "But that violates SRP!" (Single Responsibility Principle).
Whoops, I wouldn't want to do that! Or would I?
Actually, I would!