My own list of (some of the many) reasons not to use an object oriented approach that come to mind in my daily work. Started after writing this comment
I've seen quite a few good projects written in an "OOP" language, but not in an OOP style - mostly misuse classes for namespacing (which I don't think is a good idea either since it makes usages of namespaced things hard to find).
I've never seen a "true" OOP project that wasn't quite a mess and couldn't have been written much cleaner in a plain old procedural style:
Use freestanding functions, the most successful abstraction to date.
Stop the singleton BS. Most things that need to be managed exist precisely once in a program (talk to the sound card, to the printer, to the network, to the graphics card, to the file system, allocate memory...). Making classes first and instanciating once (or how many times, how can I know by looking at that handle?) is just plain silly, overly verbose, and confusing to the consumer of the API.
Don't couple allocation and initialization. It's a stupid idea. It leads to pointless, inefficient, and (in some languages) error-prone one-by-one allocations.
Flat fixed structs for data organization. By default expose struct size for massive decrease in memory allocation. Expose almost all fields (except for truly platform / implementation-defined ones) and stop with that silly getter/setter boilerplate.
Mostly use data tables (with direct integer indexing mostly) like in a relational database, for data-driven architectures. (CS/programming technology TODO: How can we switch between AOS/SOA more seamlessly? Maybe we can get inspiration from Graphics APIs?)
Don't use silly flexible-schema XML/object hierarchies to "compensate" for having no idea what's in the data. It doesn't help.
Make interfaces ("vtables" if you will) only sometimes where they are needed, not by default. Don't call this inheritance. Bullshit. It's an interface, not more, not less. If you think interface descriptions must typically be bundled with each data item, think harder. They are independent data.
We don't need no friggin "doer" objects for every simple thing. It doesn't help a bit, but only makes things less readable and more complex. Just do what needs to be done!
Some more rants I left somewhere. Not coherent arguments, and lacking context, but nevertheless all true :-). I just feel like putting them here
(I feel a little bit cynical today and will say it's typical to C++'s attitude (as opposed to e.g. C): Let users make overcomplex programs more easily, by papering over all the insanity, instead of forcing them to make a clean design).
(And as usual with OOP, you end up with terrible inefficiencies (too much allocation in this case), since the program is split into needlessly isolated parts in a futile attempt to make them "self-contained". In the end, what that does is also make everything less efficient and more complicated. And redundant, if you care to look at what actually happens as opposed to what the programmer writes).
Another important aspect: Being required to "bless" functions to operate on datastructures by making them official "member" methods leads to really intertwingled dependencies. This is totally counter to the ideal of reduced coupling that OOP promises. In reality it leads to much *more* coupling, which is one of the worst aspects of many OOP languages. The better solution is to just put free-standing functions in optional modules so as to not increase dependencies by default. In the same way, declaring private members and methods in the interface (as it is required with most OOP languages) is really bad dependency hygiene.
Object-oriented programming is the idea that you will do better by solving a hundred small and ill-defined problems than you would do by solving one bigger well-defined problem. Of course, if you write a ton more code than needed to solve each individual small problem, people will be much more impressed by your work.
Object-oriented programming is the idea that systems with many interacting parts are easier to create if you model each part as a state machine that has 1 statically confirmed state. How is this supposed to help limiting the number of possible interactions?
Object-oriented programming creates architectures that don't feel like buildings. They feel like abstract collections of rooms that have no doors, but only worm holes on the walls. You never know where something will end up if you push it through a hole. And that's a great idea (obviously). Because, abstraction, right? -.- And if you know where something must go, you're still hosed if you have no hole for it. And that's a great idea, because, encapsulation. Right?
Anyway, let's put cynicism aside for today. At least things are so much simpler and easier to grasp, thanks to the fact that the things you're pushing through worm holes are rooms themselves! Yay for homogenity.
Created: 2017-12-17. Last updated: 2018-08-29