While rooted in actual use cases, I agree that often the GoF and other patterns are applied when there’s no need. My guiding principle nowadays is deletability/unpluggability - structuring things in a way that removing a component or behavior is as easy as possible. I do need the same patterns to achieve this, but I don’t blindly apply them, and use them way less as a result. Eg, with Swift‘s value types and great closure support, I can often go 90% of the way just with structs - no interfaces (protocols) or classes needed.