This doesn't speak to what I consider some of the most dangerous parts of OOP, which include the assumptions that tightly binding data and code is helpful, and that statefulness is fine to freely sprinkle throughout your program.
So what is your preferred solution for programs that intrinsically need to deal with a lot of state ? Global variables ? I used to see that type of approach in some complex Fortran simulation programs where every function referenced a huge common block. I really don't think that leads to easier to manage solutions.
The Case Against OOP Is Wildly Overstated
181–190 of 312 posts
Re: The Case Against OOP Is Wildly Overstated
#182Since I accepted I was no Einstein I embraced the KISS principle. My code became simpler, easier to understand. Of course it wouldn't get the approval of any software architect or any design pattern fanatic, but I can take any code I wrote 3 years ago, understand it on the fly and edit it with confidence. There are few bugs and they're never a nightmare to find. Now if I have to modify the code I was writing before m…
Re: The Case Against OOP Is Wildly Overstated
#183Earlier quoted context omitted.
You might want to consider examining another programming language for clues here. Perhaps look to a language that has a more modern approach to state such as Clojure.
My understanding is that Clojure is basically lisp implemented inside the Java ecosystem. I'm not sure how that makes it "modern" given that the only higher level language older than lisp is the original version of Fortran.
Re: The Case Against OOP Is Wildly Overstated
#184Earlier quoted context omitted.
I'm not the one you're asking. But... Here's a data structure that represents a bill of materials. It has a list of components, and a total cost, which is the sum of the costs of the components on the list. That's the invariant - that the total cost is the sum of the costs of the components in the list. If it's just a structure, then someone can add or remove a component, and forget to update the total cost, and the…
For what it’s worth, with ADTs and non-exposed constructors you can achieve the same result (i.e. only the creating module can actually _build_ such a list but other modules can read the data).
Re: The Case Against OOP Is Wildly Overstated
#185Earlier quoted context omitted.
Actually my response would be that you just have a plain-ish vanilla list of `Component`, and a function `TotalCost(List[Component]) -> float`, which is implemented as, approximately, lambda arr: sum(x.cost for x in arr). This maintains the invariant without state. There's a potential performance cost here, but that usually doesn't matter a whole lot.
That's true - but where do you put the function? In a complex system I can end up with loads of these totalling functions scattered about. I might have gross and net versions of the total and, given human nature, they get created near the use of them. The variants then get duplicated. The objects give you a modular structure which means you can see the interface.There is a disconnect when you have to shift to the obj…
Re: The Case Against OOP Is Wildly Overstated
#186Re: The Case Against OOP Is Wildly Overstated
#187Earlier quoted context omitted.
I'm not the one you're asking. But... Here's a data structure that represents a bill of materials. It has a list of components, and a total cost, which is the sum of the costs of the components on the list. That's the invariant - that the total cost is the sum of the costs of the components in the list. If it's just a structure, then someone can add or remove a component, and forget to update the total cost, and the…
Actually my response would be that you just have a plain-ish vanilla list of `Component`, and a function `TotalCost(List[Component]) -> float`, which is implemented as, approximately, lambda arr: sum(x.cost for x in arr). This maintains the invariant without state. There's a potential performance cost here, but that usually doesn't matter a whole lot.
Yes, but this is not possible in general. For instance, what if you want to endow your List with a "MaxTotalCost", set at creation. You can't ensure that your list respects that invariant, other than by encapsulating it behind some custom interface.
Re: The Case Against OOP Is Wildly Overstated
#188This doesn't speak to what I consider some of the most dangerous parts of OOP, which include the assumptions that tightly binding data and code is helpful, and that statefulness is fine to freely sprinkle throughout your program.
"Tightly binding data and code" allows you to maintain complex invariants via code, and to abstract away from the specifics of any single implementation. Statefulness per se is quite manageable; what's not manageable is shared, mutable state that isn't isolated to a single, modular, highly cohesive "unit" of code that can be understood in its totality. The real issues with OOP have to do precisely with things that br…
State and zip code always change together. Having had to fix code that passed 5 variables around for an address (which needed to go to 6 for “address 2”) I replaced it with an address object.
Re: The Case Against OOP Is Wildly Overstated
#189These directly relate to some of the core features of C++ like namespaces, virtual functions, and templates.
I think this perspective makes the differences between C++ style object orientation and Smalltalk style object orientation understandable.
Re: The Case Against OOP Is Wildly Overstated
#190Earlier quoted context omitted.
The entire point of OOP is to encapsulate state within objects and to have objects communicate through messages, that is to say to 'program without a center'. Global or interconnected state is if anything a violation of OO principles. In proper OO state is hidden and insofar as it causes issues it does so in a way that is handled by the object rather than the program overall. Also treating code as data isn't a featur…
> The entire point of OOP is ... One problem is that every OOP advocate has a different perspective on "what the entire point of OOP is". Another problem is that irrespective of what any OOP advocate believes is OOP, the body of code that is commonly understood to be "OOP" is plagued with abuses of inheritance (I'm not even convinced there are legitimate uses), mutable state, the "banana with a reference to the goril…
It's true that bad OO code suffers of different problems than bad FP code, and both are different from bad procedural code. But there is no guarantee that an organization which produced bad OO code would have produced good FP code, just as there was never a reason to imagine (though many did) that an organization that produced bad procedural code would produce good OO code if forced to switch to OO.
In general, there is no solver bullet. We can absolutely replace the problems specific to bad OO code with problems specific to bad FP code if we move from OO to FP, but we cant be sure of any other outcome.
More likely than not, we need to change more than the style of code we build if we want to take an org that has produced bad code and make it produce good code - we should change incentives, testing, goals, timelines etc.
And just to be clear, you're absolutely right that saying 'that's not good OO code' is no-true-Scotsman and not helpful in any way, other than pointing out that it is possible to produce good OO code (some people doubt that, I think).