Graham Lee writes about software design, object-oriented programming, Objective-C and the limits of common programming practices.
Commenters recommend his posts on inheritance and 'Discipline Doesn't Scale' as helpful, though one found the closing paragraphs of a post disappointing.
> traditional gratuitous use of object classes for everything
This sort of phrasing is sort of distressingly characteristic of contemporary discussions about object-oriented programming.
I can understand where it comes from - if you look through my comment history, you'll probably find plenty of examples of me running my mouth about Java or the overuse of OOP in Python - but I assure you there is a baby in all of that bathwater, and it doesn't need to be thrown out. That baby is dynamic dispatch, and it does let you do some things that can be a hassle without it.
Unfortunately, it tends to be poorly taught or poorly understood nowadays. This is not a "no true Scotsman" argument. I'm not saying no true hammer would be used to drive screws. I'm just observing that, if a carpenter was never taught about screwdrivers, it's no surprise they'll develop a lot of pent-up frustration about hammers, and perhaps even be a bit confused about what they're really for. It seemed to me that one of the core sections of the essay ikrubner linked above rested on a conflation of dynamic dispatch and dynamic typing. Which is a worrisome thing I've seen many people do. It's no wonder we don't use OOP well, living in an intellectual environment where its only truly distinguishing characteristic rarely even makes it into lists of its key features. So, perhaps it's even worse than just having only been given a hammer. We were only given a hammer, and were also never taught about nails.
Anyway,…
I'm all too aware of these many citations. A few years ago, I went to the trouble of chasing down most of the papers and books, and evaluating how well each of them supported the claim. To put it mildly, I was underwhelmed.
For just one example, here's my treatment of Grady: http://lesswrong.com/lw/9sv/diseased_disciplines_the_strange_case_of_the/
It's not just me. Here's another author of a book aimed at software professionals who attempted some fact-checking, and came up short: http://www.sicpers.info/2012/09/an-apology-to-readers-of-test-driven-ios-development/
I, too, used to argue for practices such as test-driven development, based on the supposedly firm knowledge of the "cost of defects curve". I changed my mind about the cost of defects when I saw how poor the data was. This is me in 2010: http://lesswrong.com/lw/2rc/coding_rationally_test_driven_development/2qnl and this is me two years later, recanting: http://lesswrong.com/lw/2rc/coding_rationally_test_driven_development/7c6g
However, I haven't (entirely) changed my mind about TDD and similar practices. I do still believe it pays to strive to write only excellent code that is easy to reason about. I like to think that I now have stronger and better thought out reasons to believe that.
It is not critical but I think it is interesting.
For example, I've read Code Complete 2, and while browsing online I found that some of the claims in the book was not solid.
- https://www.sicpers.info/2012/09/an-apology-to-readers-of-test-driven-ios-development/
- https://www.lesswrong.com/posts/4ACmfJkXQxkYacdLt/diseased-disciplines-the-strange-case-of-the-inverted-chart
The point made in the above links are interesting but, because I remember reading this particular book, they are sticking more deeply in me.
Also it probably depends heavily on the topic.
For example in economic or philosophy, there are different schools of thoughts and I think it is valuable to know from which school a "fact" is attached to. And before learning about every school, it is probably easier to just remember where you first read it.
This is not critical, but maybe having this information can help you create new insights.
On inheritance: https://www.sicpers.info/2018/03/why-inheritance-never-made-any-sense/
On encapsulation: I joke that encapsulation on a level of an object is like putting a lockpad on your right pocket to protect your left hand from reaching to it.
Normal people keep doors and locks at the entrance of a door or a room (module level), not on every single object they have. That's why OOP software tends to look so schizophrenic: with walls erected between everything against everything, making stuff like https://github.com/Hello-World-EE/Java-Hello-World-Enterprise-Edition possible.
You might check some of my blogposts at dpc.pw if you care to read more of my thoughts on this.
My suggestion is Objective-C. It's just so weird to anyone who's never coded in it, that it will force you out of your comfort zone into new ways of thinking. The NS framework is probably the most well designed stdlib of any language ever, and the whole thing is inspired directly from Smalltalk. Protocol Oriented Programming [0] was also a real revelation for me, and I still apply those concepts anywhere I can. It's also a great introduction to lower level concepts like pointers and memory management that is a lot more forgiving than C/C++.
[0] https://www.sicpers.info/2015/06/protocol-oriented-programming-in-objective-c/
I agree the post is great (which is why I submitted it) but I also found the last couple of paragraphs kind of a let down, after nodding along enthusiastically for the rest of the article.
The article links to this other post on a similar topic https://www.sicpers.info/2021/03/one-person-per-task/. The advice there boils down to "hey, remember agile? Not just the 'use Jira' but, but the rest of it. That was a good idea!"