less_retarded_wiki/oop.md
Miloslav Ciz 805062a922 Update
2022-04-29 18:26:15 +02:00

40 lines
7.2 KiB
Markdown

# Object-Oriented Programming
*"I invented the term 'object oriented' and [C++](cpp.md) was not what I had in mind"* --[Alan Kay](alan_kay.md), inventor of OOP
Object-oriented programming (OOP, also object-obsessed programming) is a [programming paradigm](paradigm.md) that tries to model reality as a collection of abstract objects that communicate with each other and obey some specific rules. While the idea itself isn't bad and can be useful in certain cases, OOP has become extremely overused, extremely badly implemented and downright forced in programming languages which apply this [abstraction](abstraction.md) to every single program and concept, creating [anti-patterns](anti_pattern.md), unnecessary issues and of course [bloat](bloat.md). We therefore see OOP as a [cancer](cancer.md) of software development.
Ugly examples of OOP gone bad include [Java](java.md) and [C++](cpp.md) (which at least doesn't force it). Other languages such as [Python](python.md) and [Javascript](javascript.md) include OOP but have lightened it up a bit and at least allow you to avoid using it.
You should learn OOP but only to see why it's bad (and to actually understand 99% of code written nowadays).
## Principles
Bear in mind that OOP doesn't have a single, crystal clear definition. It takes many forms and mutations depending on language and it is practically always combined with other paradigms such as the [imperative](imperative.md) paradigm, so things may be fuzzy.
Generally OOP programs solve problems by having **[objects](object.md)** that communicate with each other. Every object is specialized to do some thing, e.g. one handles drawing text, another one handles [caching](cache.md), another one handles rendering of pictures etc. Every object has its **data** (e.g. a human object has weight, [race](race.md) etc.) and **methods** (object's own [functions](function.md), e.g. human may provide methods `getHeight`, `drinkBeer` or `petCat`). Objects may send **messages** to each other: e.g. a human object sends a message to another human object to get his name (in practice this means the first object calls a method of the other object just like we call functions, e.g.: `human2.getName()`).
Now many OO languages use so called **class OOP**. In these we define object [classes](class.md), similarly to defining [data types](data_type.md). A class is a "template" for an object, it defines methods and types of data to hold. Any object we then create is then created based on some class (e.g. we create the object `alice` and `bob` of class `Human`, just as normally we create a variable `x` of type `int`). We say an object is an **instance** of a class, i.e. object is a real manifestation of what a class describes, with specific data etc.
OOP furthermore comes with some basic principles such as:
- **[encapsulation](encapsulation.md)**: Object should NOT be able to access other object's data directly -- they may only use their methods. For example an object shouldn't be able to access the `height` attribute of a `Human` object, it should be able to access it only via methods of that object such as `getHeight`. (This leads to the setter/getter antipattern).
- **[polymorphism](polymorphism.md)**: Different objects (e.g. of different classes) may have methods with the same name which behave differently for either object and we may just call that method without caring what kind of object that is (the correct implementation gets chosen at runtime). E.g. objects of both `Human` and `Bomb` classes may have a method `setOnFire`, which with the former will kill the human and with the latter will cause an explosion killing many humans. This is good e.g. in a case when we have an array of [GUI](gui.md) components and want to perform e.g. resize on every one of them: we simply iterate over the whole array and call the method `resize` on each object without caring whether the object is a button, checkbox or a window.
- **[inheritance](inheritance.md)**: In class OOP classes form a hierarchy in which parent classes can have child classes, e.g. a class `LivingBeing` will have `Human` and `Animal` subclasses. Subclasses inherit stuff from the parent class and may add some more. However this leads to other antipatterns such as the [diamond_problem](diamond_problem.md). Inheritance is nowadays regarded as bad even by normies and is being replaced by [composition](composition.md).
## Why It's Shit
- For simple programs (which most programs should be) OOP is an unnecessarily high and overly complex abstraction.
- OOP is just a bad abstraction for many problems that by their nature aren't object-oriented. OOP is not a [silver bullet](silver_bullet.md), yet it tries to behave as one.
- Great number of the supposed "features" and design-patterns (setters/getters, singletons, inheritance, ...) turned out to actually be anti-patterns and burdens.
- OOP as any higher abstraction very often comes with overhead, memory footprint and performance loss ([bloat](bloat.md)) as well as more complex [compilers](compiler.md) and language specifications.
- The relatively elegant idea of pure OOP didn't catch up and the practically used OOP languages are abomination hybrids of imperative and OOP paradigms that just take more head space, create friction and unnecessary issues to solve. Sane languages now allow the choice to use OOP fully, partially or avoid it completely, which leads to a two-in-one overcomplication.
- The naive idea of OOP that the real world is composed of nicely defined objects such as `Human`s and `Tree`s also showed to be completely off, we instead see shit like `AbstractIntVisitorShitFactory` etc.
- The idea that OOP would lead to code reusability also completely went to shit, it's simply not the case at all, implementation code of specific classes is typically burdened with internal and external dependencies just like any other bloated code.
- Good programmers don't need OOP because they know how to program -- OOP doesn't invent anything, it is merely a way of trying to **force** good programming mostly on incompetent programmers hired in companies, to prevent them from doing damage. However this of course doesn't work, a shit programmer will always program shit, he will find his way to fuck up despite any obstacles and if you invent obstacles good enough for stopping him from fucking up, you'll also stop him from being able to program something that works well as you tie his hands.
- OOP just mostly repeats what other things like modules already do.
- If you want to program in object-oriented way and have a good justification for it, **you don't need an OOP language anyway**, you can emulate all aspects of OOP in simple languages like C. So instead of building the idea into the language itself and dragging it along forever and everywhere, it would be better to have optional OOP libraries.
- It generalizes and simplifies programming into a few rules of thumb such as encapsulation, again for the sake of inexperienced noobs. However there are no simple rules for how to program well, good programming requires a huge amount of experience and as in any art, good programmer knows when breaking the general rules is good. OOP doesn't let good programmers do this, it preaches things like "global variables bad" which is just too oversimplified and hurts good programming.
## History