Live data from Hacker News

Premature Abstraction

arendjr.nl

61–70 of 116 posts

Re: Premature Abstraction

#61
Though I agree about the point about not creating objects/instances where a pure function will get the job done, I disagree with the general stance against OOP. I think OOP is absolutely essential to simplicity. FP tends to lead to too many indirections with data traversing too many conceptual boundaries. FP (if used dogmatically) tends to encourage low cohesion. I want high cohesion and loose coupling. Some degree of co-location of state and logic is important since that affects cohesion and coupling of my modules.

The key to good OOP is to aim to only pass simple primitives or simple cloned objects as arguments to methods/functions. 'Spooky action at a distance' is really the only major issue with 'OOP' and it can be easily solved by simple pass-by-value function signatures. So really, it's not a fundamental issue with OOP itself. OOP doesn't demand pass by reference. Alan Kay emphasized messaging; which is more leaning on 'pass by value'; a message is information, not an object. We shouldn't throw out the baby with the bathwater.

When I catch a taxi, do I have to provide the taxi driver with a jerrycan full of petrol and a steering wheel? No. I just give the taxi driver the message of where I want to go. The taxi driver is responsible for the state of his car. I give him a message, not objects.

If I have to give a taxi driver a jerrycan full of petrol, that's the definition of a leaky abstraction... Possibly literally in this case.

That said, I generally agree with this article. That's why I tend to write everything in 1 file at the beginning and wait for the file size to become a problem before breaking things up.

There are many different ways to slice things up and if you don't have a complete understanding of your business domain and possible future requirement changes, there is no way you will come up with the best abstractions and it's going to cost you dearly in the medium and long term.

A lot of developers throw their arms up and say stuff like "We cannot anticipate future requirement changes"... Well of course, not on day 1 of your new system!!! You shouldn't be creating complex abstractions from the beginning when you haven't fully absorbed the problem domain. You're locking yourself into anti-patterns and lots of busy-work by forcing yourself to constantly re-imagine your flawed original vision. It's easier to come up with a good vision for the future if you do it from scratch without conceptual baggage. Otherwise, you're just seeding bias into the project. Once you have absorbed it, you will see, you CAN predict many possible requirement changes. It will impact your architecture positively.

Coming up with good abstractions is really difficult. It's not about intelligence because even top engineers working in big tech struggle with it. Most of the working code we see is spaghetti.

Re: Premature Abstraction

#62
post #4

Although I agree with the recommendations, I cringe at the definition of abstraction. In a sane world, abstraction doesn't mean defining classes so much as it means identifying important unifying concepts. DRYing your code by moving a method to a common base class isn't abstraction in any important way, it's just adding a level of indirection. In fact, I'd argue that this example is the opposite of abstraction: it's…

I'm currently dealing with a codebase that does this to a ridiculous extent. Like, literally, every change affects the entire project because everything is made of base-classes mixed in weird ways. Every concrete object inherits multiple base classes and no individual behavior. Imagine something like this: class Book extends ShelfableItem, Pagable, Authored, Readable, BaseBook {} It's absolutely insane.

crying in rails concerns :*-(

Re: Premature Abstraction

#63

My general take (and w/ the caveat that every system is different) is as follows: - procedural code to enter into the system (and perhaps that's all you need) - object oriented code for domain modeling - functional code for data structure transformations & some light custom control flow implementation (but not too much) I like the imperative shell, functional core pattern quite a bit, and focusing on data structures…

OO code for domain modeling might be, to date, the single greatest source of disillusionment in my career. There are absolutely use cases where it works very well. GUI toolkits come to mind. But for general line-of-business domain modeling, I keep noticing two big mismatches between the OO paradigm and the problem at hand. First and foremost, allowing subtyping into your business domain model is a trap. The problem i…

I'm not a big thinker on such things, but my general rule is that subtyping is okay only for implementation details.

I.e. it's okay for ConsoleLogger to be a subtype of Logger, but PaidUser probably shouldn't be a subtype of User.

Re: Premature Abstraction

#64

I'm not "formally" trained in software engineering and am primarily self-taught. This area, in particular, has been confusing to me over the years, especially after consuming so many contradictory blog posts. I tried to model DDD in a recent Golang project and am mostly unhappy with the result. Perhaps in my eagerness, I fell into the trap of premature abstraction, but there's not anything in particular that I can po…

> I'm not "formally" trained in software engineering and am primarily self-taught

Welcome to the club and I wouldn't be too worried about it (but definitely read and learn what others have figured out).

Software design and development is still an unsolved problem. The industry has not collectively found a foundational set of standard practices that apply across the board other than some of the most basic (e.g. organization is good).

You can tell that it's not solved by the relentless flow of industry trends that become the new "best practice" until some years later when we figure out "well, that approach has these pros and these cons and tends to fit with these types of problems, but definitely not a silver bullet, let's try the next thing"

Regarding your specific issue on your new project: just be pragmatic, get it working and learn from your decisions, it's all just a collection of pros and cons and the analysis of pro vs con changes depending on the angle you look at it (e.g. short term vs long term, slow changing environment vs fast changing environment, cost to value ratio, etc., etc., etc.)

Re: Premature Abstraction

#65
post #15

Earlier quoted context omitted.

OO code for domain modeling might be, to date, the single greatest source of disillusionment in my career. There are absolutely use cases where it works very well. GUI toolkits come to mind. But for general line-of-business domain modeling, I keep noticing two big mismatches between the OO paradigm and the problem at hand. First and foremost, allowing subtyping into your business domain model is a trap. The problem i…

This is a strong argument against inheritance, but that isn't everything about OOP. Just one well supported advanced abstraction (That I would also argue should be rarely used.) I would argue that just having strong type system and bundling methods with data gets you the vast majority of the usefulness of OOP. Liskov, Open/Closed, Message Passing, and other theoretical abstractions be damned. EDIT - Where are the goo…

> I would argue that just having strong type system and bundling methods with data gets you the vast majority of the usefulness of OOP.

Yes, a module system brings almost all of the advantages of OOP. The one remaining is structure abstraction (things like interfaces on Java derived languages, or type classes on Haskell derived ones).

But well, none of those are even typically associated with OOP. The OOP languages just have those features, like they have variables too.

Re: Premature Abstraction

#66

I'm not "formally" trained in software engineering and am primarily self-taught. This area, in particular, has been confusing to me over the years, especially after consuming so many contradictory blog posts. I tried to model DDD in a recent Golang project and am mostly unhappy with the result. Perhaps in my eagerness, I fell into the trap of premature abstraction, but there's not anything in particular that I can po…

The one point of DDD is that you make a dictionary of all of the domain terms and get everybody to accept them.

You can cut those 4 pages and throw the rest of the book away. But it is one of the best books on software engineering, and only gets better once you do that.

Re: Premature Abstraction

#67
Gall’s law: “A complex system that works is invariably found to have evolved from a simple system that worked. The inverse proposition also appears to be true: A complex system designed from scratch never works and cannot be made to work. You have to start over, beginning with a working simple system.”

Your theory of premature architecture reinforces Gall’s law.

This is from the book Systemantics: How systems work and especially how they fail (1977).

https://en.wikipedia.org/wiki/Systemantics

Re: Premature Abstraction

#68
post #45

Earlier quoted context omitted.

The keyword to search for is algebraic data types, which are common in functional languages, but for instance Rust also has them. Here is an example comparing C# with F#, where the latter also algebraic data types: https://blog.ploeh.dk/2016/11/28/easy-domain-modelling-with-...

The syntax has improved quite substantially since 2016 for pattern matching at C#'s end, and it's very easy to model ADTs with records (and the experience of using them even before that was decent with methods accepting lambdas). Today, you write it in a similar way you would write a match in Rust.

How do you represent sum types in C# today? Can enum members hold records as data, or do you do it differently?

Re: Premature Abstraction

#69
post #33
post #25

Earlier quoted context omitted.

If you think OOP is particularly well-suited to domain modelling, you should try the FP approach to domain modelling. You will never be able to unsee the complexity inherent to OOP.

Do you happen to have a link to an example or explanation?

Domain Modeling Made Functional [0] by Scott Wlaschin

[0] https://www.youtube.com/watch?v=2JB1_e5wZmU

Re: Premature Abstraction

#70

Earlier quoted context omitted.

OO code for domain modeling might be, to date, the single greatest source of disillusionment in my career. There are absolutely use cases where it works very well. GUI toolkits come to mind. But for general line-of-business domain modeling, I keep noticing two big mismatches between the OO paradigm and the problem at hand. First and foremost, allowing subtyping into your business domain model is a trap. The problem i…

But, in a way, OO modeling and design was invented to solve the mess that "banging out" procedural code created in the first place. You have to model your business domain in software one way or another anyway. Why should it be bad to try to be more methodical about it using OO methods? We do it with relational databases all the time where tables are pretty similar to objects.

OO and Relational databases really don't mix well, so much that there are wikipedia articles on the subject [0].

ORMs create some of the worst SQL table layouts that I've ever seen, not to mention they generally cause tons of N+1 query problems.

[0] https://en.wikipedia.org/wiki/Object%E2%80%93relational_impe...

Post reply on HN