- Paradigm - a typical example or pattern of something; a model.
- Methodology - a system of methods used in a particular area of study or activity.
The definition of each is quite similar. OOP may be a paradigm by Wikipedia's definition, however I'd posit that in practice OOP becomes a mere methodology, aka a way for "engineers" to mindlessly follow "principles" in order to try and write good code. Here's a quote from the CTO of Activision. Here's Paul Graham on OOP -- he says what I'd like to say, but said it first and better than I would. Here's Casey Muratori on OOP. Here's Casey again. Sony dudes on OOP.
The idea is that OOP is designed in such a way that it appears to give rise to good code. Take the OOP example my link github repository and look at main.cpp. Wow! That code is so readable! And here I think is where the problem surfaces. Sure, the concept of what the code is doing in theory may be clear, and it might be human readable and perhaps human related. These are all great things. However these are not the only criteria for what makes code good. Some more criteria are things like: can we reason about what assembly will be generated? Do we know what kind of impact this code has on compile time? Can we tell, at all, just by reasoning at-a-glance what the hardware will do when running this code? When OOP code is involved all of these qualities are lost in the mist of OOP-ey abstraction.
As an alternative I would say that OOP doesn't actually solve real problems. OOP presents a solution to imaginary organizational problems and tricks people into thinking they are being productive by solving organizational non-problems.
Take a look at the examples jjf and myself created. I'd say both OOP implementations are quite similar. I'd also say both OOP implementations are fairly canonical and would be widely considered as a pretty good standard OOP implementation:
Github repo of my imeplementation of OOP vs non-OOP of a CSV serializer for C structs: https://github.com/RandyGaul/oop
jjf's OOP implementation: http://puu.sh/q7HaQ/4df33d2501.7z
Pros of the non-OOP implementation:
- Super simple and easy to read.
- Trivial to extend and add more types.
- Not much code.
- The algorithm is laid out linearly in code. It's just right there, in front of you. No boilerplate.
- Solves exactly the problem of CSV serialization without attempting to solve any other problems. This adds code-reusability.
Some Cons of the OOP implementation:
- Lots of code for solving a very simple problem.
- Extremely tempting to solve-non problems, or create more problems that don't need to exist. Added a constructor? What about the copy constructor? Or move constructor? What about private and public, and encapsulation? Good OOP has to have encapsulation right? Also we should probably have some inheritance and polymorphism in there too. In the end I sacrificed performance for the sake of following OOP principles -- these principles let the OOP implementation be extended and scaled into the future! Right? RIGHT???
- Tons of functions all over the place. It seems like the algorithm was splat onto the floor and left there to congeal. Following code flow involves lots of opening and closing of different files and looking all around. It's just a mess.
Some immediate concerns may be that my OOP implementation was poor, or bad. Okay, how can it be fixed? Don't just tell me, go fix it. I have an open-source github page, so go make a pull request. I won't accept any unfair criticism of the presented source unless time is put into making an actual example for real discussion.
Another concern is that many cons of the OOP implementations here are that they are all C++-ey, riddled with C++ problems, not OOP problems. Well, same as my previous point -- I don't care unless you write up an example and create a pull request on github, or upload your own repository and share some code. Unless we have an example to work with criticizing the existing examples won't really get us very far.
In conclusion OOP sucks, everyone using OOP should stop, OOP code is bloated, usually has tons of dependencies, performs slowly, compiles slowly, is hard to modify and multi-thread, and solves many problems that don't really exist. Instead problems should be taken case-by-case where specific solutions are used to solve specific problems. One problem, one solution. Avoid "generic" code that attempts to solve many problems at once. Re-usable code is code that *isn't* generic (like the STB libraries), because people can figure out how to use it and solve the problem they have without worrying about extra bloat, extra dependencies, or extra bullshit.