6 ms·
> The solution to the fragile base class problem and other inheritance hangovers is surprisingly simple — don’t use it If OOP provides the footgun to shoot you
by clktmr 6y ago
> The solution to the fragile base class problem and other inheritance hangovers is surprisingly simple — don’t use it
If OOP provides the footgun to shoot yourself, OOP is at fault. Overall the article reads as "OOP has no problems if is used correctly". Of course that's true. I have seen well designed OOP programs, but the majority was not. The author should ask the question, why OOP is applied the wrong way so often.
- Rickasaurus 6y agoThe 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.
- dionian 6y agoWith more power comes more need for discipline.
- jcelerier 6y ago> The author should ask the question, why OOP is applied the wrong way so often. well, if universities started by teaching something else that "Cat" inherits "Animal" in 2020 ...
- jerf 6y agoPersonally, I think this is a large part of the problem with the whole "Is OO Good?" debate. OO was initially thought to be a solution to essentially simulations problems ("Simula"[1] - the first OO language - it was right in the name!), where Cat inheriting Animal makes sense. It turns out this translates to general purpose programming exceedingly poorly. It spends your valuable class hierarchy budget on the wrong things, while discouraging spending it on the right things. On the other hand, OO turned out to be a useful gateway into polymorphic programming (not the only one, but a useful one), and to be a useful organization principle in real programs when used differently. Instead of Cats inheriting from Animals, you have interfaces for things like Iterators, which aren't real world objects at all, and you have objects that encapsulate certain operations, or certain patterns, or other much more abstract things that have no concrete physical referent. This style can work fairly well, especially if you don't overuse inheritance. The simulation argument has really faded in the past 20 years, but even now, you get some crossfire between people attacking that formulation vs. people defending the modern version, and they're talking about such different things they might as well not even be talking about the same paradigm. And as is typically the case, education is a lagging indicator, and even fairly recently I've seen it training people on the simulation model, even though by the 2010s it was pretty clearly useless in practice. [1]: https://en.wikipedia.org/wiki/Simula https://en.wikipedia.org/wiki/Simula
- deleted 6y ago[deleted]
- mpweiher 6y agoSure 90% of OOP is crap, that's because 90% of everything is crap. https://en.wikipedia.org/wiki/Sturgeon%27s_law https://en.wikipedia.org/wiki/Sturgeon%27s_law
- liability 6y ago10% of OOP isn't crap? God I wish I could believe that was true. Unfortunately, Sturgeon's Law is just a lower bound.