4 ms·
The term we like to use is "the pit of success". It shouldn't be hard to do it the right way.
by Rickasaurus 6y ago
The term we like to use is "the pit of success". It shouldn't be hard to do it the right way.
- infogulch 6y agoYou are a ball. Do you want to naturally roll towards the pit of success, or struggle to balance yourself atop the tower of abstractions?
- beaker52 6y ago"The pit of success" is a great guiding principle when it comes to the design of codebases. Forget about "design patterns" and just focus on _how do I allow developers to focus on creating things that are adding value, rather than faffing around with extraneous things_. I can't tell you how many times I've seen a project go full onion-pattern with a web service that basically just recieves HTTP requests and makes a few itself and returns some data. Instead of a HTTP request handler that fetches data, perhaps does some mutation and returns it, there's a whole "service layer", a domain model, data fetching abstraction. To change something you have to navigate the winding dependency graph and fight off all the deamons. That's not the pit of success, they're the catacombs of failure. We should design codebases so that future developers fall into the pit of success, even if it means we haven't been able to show off our knowledge of software architecture etc. The best pattern you can ever apply, is the one that makes change easiest. If you make change hard, the code becomes artificially stale -- I call it 'calcified'. Coupling makes code hard to change. Thinking about problems through objects, in my experience, encourages people to make 'one model to rule them all', for example in a retail app, you might have a "Product" which ends up having product information, media assets, pricing, promotions, retail and stock keeping information etc which in a peice of software undergoing 'rapid development', multiplies the likelihood of coupling. Which is where Domain Driven Design steps in and tries to preach. Thinking about your problem in terms of data, or events can often help you find the right concepts to create your abstractions around. Another good heuristic is to think about caching, can you cache pricing for the same length of time you can cache product information, for example? Bit of a ramble, but explains why I tend to shy away from objects, except for where I have a bonafide business problem that needs to be modelled -- with this, the models are only used to make the code make sense to developers and help arrive at the result they produce, rather than the models being the result themselves.
- vsareto 6y agoOOP is conducive to premature optimizations. It hints for you to find the right abstraction for future problems, because that's where the productivity gain supposedly is. Instead of rebuilding cars from scratch every time (in the future), I have an interface. Learning it starts to train you to look for these opportunities, and eventually you start thinking "what if this class becomes a foundational class? I want everyone working on it to have a great time. I don't like being cursed out for not predicting the obvious future", and so now there's a bunch of onion-y stuff added.
- dclusin 6y agoFor large interwoven software systems this complexity seen in the form of service layers, directory services, distributed quorums, etc. is often necessary to achieve availability guarantees. I think that the problem is that engineers are over eager to design these sorts of things and implement them before they're actually necessary. And they do it badly and make life shitty in the process because they still don't fully understand the requirements for such a system. OOP just happens to be the language feature they use to make a mess. It would still be no fun even if they used a straight procedural language like C.
- kqr 6y agoAdding on to this, there's an important distinction described by Parnas back in the 1970s as > Software can be considered "general" if it can be used, without change, in a variety of situations. Software can be considered "flexible", if it is easily changed to be used in a variety of situations. We frequently forget that these are both valid paths to the same end. We tend to laser-focus in on generality, at the expense of flexibility. And for small problems like the one described, it is usually much easier to go for flexibility at the expense of generality. And I think we should.
- TheOtherHobbes 6y agoThe onion anti-pattern is Separation of Concerns taken as mythology, not practicality. A reasonable way to OOP is: 1. Understand your domain and work hard to match its structures. 2. Delegate and separate where there's an unquestionable benefit, not for the sake of it. 3. Likewise for inheritance hierarchies. 4. Don't create entities unnecessarily. Every single decision should have a clear practical rationale. SOLID on its own is not a rationale - it's a guide, but to use it you need to understand what a concern is from the domain POV, not from the code POV.