For a short intro to Sandi's style and approach, I always recommend this 35min talk: https://youtu.be/OMPfEXIlTVE?si=Ird6t8uDN86T06Y7
Aside from any specifically educational content, as a talk it is fantastic - funny, smart, well put together.
I'm very happy to see it out for Python!
Reading these two really helped me understand just how impoverished the concept of OOP has become by C++ and Java, from its Smalltalk roots.
Very helpful and clear thinking about refactoring out complexity—and not just refactoring for its own sake, but under the constraint that you want to move your program forward, add new functionality, etc. Refactoring with a direction, purpose, and direct payoff.
I had the same "this isn't realistic!" complaint when studying the book, but the examples nonetheless helped me see, practice, and adopt the techniques so that I could immediately apply them to the complex production examples I needed to improve. YMMV... but as a former skeptic, "trust the process." Walk that path an work those examples for 5 days, then see how you feel. I was already pretty skilled, including in complex refactorings, and it still leveled me up.
I've never really had the problem that I've read an OOP text and felt "this was too short".
The site says, "Available in digital form only (epub, kepub, mobi, pdf). Includes separate books for JavaScript, PHP, Python, and Ruby languages, and beer and milk beverages."
There is no mention of needing special software to read them, so I think it's safe to guess that there is no DRM. And it's sold directly by the author. Publishers are generally the ones who insist on DRM. It would not surprise me if there was watermarking, but that is not DRM.
Bottles of OOP - https://news.ycombinator.com/item?id=12129821 - July 2016 (71 comments)
Class Foo.__init__(self, db, blob_storage, secrets_manager, …)
Instead of class Foo(DB, BlobStorer, SecretsMgr)
Etc
I'm not rabidly anti-OOP, but the point at which I turn against it is when the pursuit of "properly" modelling your domain with objects obscures the underlying logic. I feel like this book reaches that point. This is her stance on polymorphism:
> As an OO practitioner, when you see a conditional, the hairs on your neck should stand up. Its very presence ought to offend your sensibilities. You should feel entitled to send messages to objects, and look for a way to write code that allows you to do so. The above pattern means that objects are missing, and suggests that subsequent refactorings are needed to reveal them.
Absolutely not! You should not, as a rule, be replacing conditional statements with polymorphic dispatch. Polymorphism can be a useful tool for separating behaviour into modules, but that trade-off is only worthwhile when the original behaviour is too bloated to be legible as a unit. I don't see an awareness of that trade-off here. That's my problem.
Anyways yeah give me composition and flat classes all day long.
The GoF book (the design patterns book) says in a page right near the start, "Prefer composition over inheritance", in the middle of an otherwise blank page, presumably to emphasize the importance of that advice.
As others have replied, composition is one technique you can use in OOP, not something that is the opposite of OOP.
You can also use composition in non-OOP procedural languages like C, by having a struct within a struct.
https://www.google.com/search?q=can+you+have+nested+structs+...
And I would guess that likewise there are still a lot of people that don’t know this.
Also, sometimes one might not realize that the title got changed until it’s too late to edit the title of the post.
Demonstrating for the umpteenth time that automated clairvoyance is an idiotic idea.
I think you're confusing "OOP is used in projects and I've seen accidental complexity in projects" with "OOP generates accidental complexity".
The truth of the matter is that developers create complexity. It just so happens that the vast majority use OOP.
I challenge you to a) start by stating what you think OOP is, b) present any approach that does not use OOP and does not end up with the same problems, if not worse.
b) The best style is no style, or at least pick a more recently popular dogma like FP, at least it gets you easy/safe parallelism in exchange for throwing some of the tools out of your toolbox.
B. Functions and structs.
Meanwhile its creators can not hold the whole complexity in mind (often barely in spec) and still can produce a artifact that produces correct results.
And that "ton" is still miniscule compared to front-end development which almost completely eschews OOP and has 10x more incidental complexity.
I guess my point is that, while OOP's incidental complexity is large, it's still insignificant compared to other technology stacks which developers are showing a great appetite for anyway. Things like "incidental complexity" is irrelevant to developers anyway, today, at the tail end of 2024.
IOW, OOP introduces significantly less $BAD_THING, when the clear majority of developers don't even care about the quantity of $BAD_THING in the first place, making the whole "should we use OOP" argument moot.
Doesn't matter if you use it or not, the extra introduced incidental complexity is still going to be insignificant due to the complexity load of the entire project, more so in front-end.
Hence, there's no point in having the argument in the first place.
1. its ok to add incidental and unnecessary complexity
2. so long as it's less complex than your most complex component?
Because that's a formula we can all agree leads no where good nor productive.
Code in any form can generate a ton of incidental complexity. The issue isn't the tool rather than the education to properly wield those tools. Especially when you introduce the team dynamic where everyone has varying understandings of what is being built and how it should be built.
That's all I got. Best of luck!