Life is so easy if you follow a method ("Gitflow"!). Or use a framework ("Spring"!). Or implement a guideline ("Here's how you do functional programming on immutable data structures!"). The more specific, the better - it simplifies the judgment criteria whether you've done your (engineering) work well or not:
- did you follow the idiomatic way of using X?
- are the "best practices" (defined by the inventors of X) in use?
- didn't you "pollute" the solution with non-canonical, unorthodox blasphemies?
That's why we engineers keep referring to thought constructs like design patterns, XP, "Clean Code", event-sourcing, or tactical DDD. It provides us a lot of comforts, thanks to millions of howtos, templates, walkthrough tutorials, etc.
They make the ambiguity perish. But their applicability is very narrow.
Mathias Verraes has nailed it down even better one day on social media:
"I wonder sometimes if many programmers are uncomfortable with design because it doesn't fit with the 'programming is puzzle solving' framing. You can get 'in the zone' when coding, but not when making design tradeoffs. There's no ostensibly correct answer, no dopamine hit."
While I totally agree with Mathias here, I strongly believe this thought applies in a much broader scope. For pretty much every topic/problem that:
- ... is unique (can't be generalized or decomposed into independent, smaller problems) and/or has vaguely defined boundaries (context, input, output, etc.) - so you can't evaluate your solution comparatively against something you know is "100% correct"
- ... is complex enough that one can't quantify (and sometimes even properly assess) all the consequences of your decisions/actions (e.g., cascading impact on non-functional properties: performance, availability, maintainability, etc.)
That's why the observation mentioned above applies not only to functional/logical design but also to disciplines like infrastructure/system design, organizational design, process design, ... Pretty much everywhere where there are (quoting Mathias) tradeoffs to be made. Why so? Tradeoffs are "unclean" and "unaesthetic". They do not "click" with our desire for simplicity and ... engineering perfection.
Tradeoffs introduce uncertainty.
Tradeoffs are frequently imprecise as they balance somewhere between extremes of the scale. Tradeoffs are often temporary and require re-evaluation (after some time), making them even more relative (while engineers worship absolutes and objective, eternal truths).
Implications are well-known: analysis-paralysis, unconscious drift toward more comfortable problems ("Clean Code!"), and cargo cults. But that's exactly where the (real, practical) EXPERIENCE makes a helluva difference.
Thanks to all those battle scars you've acquired by tackling different problems under varying conditions (and tasting the consequences of your decisions!) for so many years, you're now less prone to the fear of making an imperfect, inadequate, suboptimal decision.
Experience deepens your understanding of the context and makes deliberate decision-making easier. Uncertainty gets replaced with clarity. You know what to watch for (because it has burned you so many times already) and maybe even how to avoid it :).
That's why, if you want to be a successful engineer, you should always plan and lead your career in a way that is optimized for acquiring a variety of high-value experiences instead of sheer money or the number of flashy acronyms in your resume.