Hacker News new | past | comments | ask | show | jobs | submit login

Thanks for the detailed explanation, I understand your point now, but I'm still not convinced that it can't be avoided/managed properly.

The primitive jungle class example you provided is actually just a condensed view of a jungle, holding counters of 'bananas' and 'gorillas', it only entangles two "counters" which is perfectly fine:

   class Jungle:
      int bananaCount;
      int gorrillaCount;

      removeBananaFromJungle():
         bananaCount -= 1;
Now lets say we improve it to add actual 'banana' and 'gorilla' classes, it may look something like this:

   class Jungle:
      List<Banana> bananas;
      List<Gorilla> gorrillas;

      removeBanana(banana):
         bananas.remove(banana);
In this example 'Jungle' is only an aggregate of 'Banana' and 'Gorilla', whose behavior is abstracted away in their classes. Moreover 'Jungle' only implements association logic. It's completely possible to define another aggregate class for a space station that reuses bananas and gorillas in a different manner:

   class SpaceStation:
      List<Banana> bananas;
      List<Gorilla> gorrillas;

      removeBanana(banana):
         bananas.remove(banana);
You could even allocate bananas and gorillas separately in your program (or unit tests) and play with them if you desire, without an aggregation class managing them. The important thing here is to promote cohesion and avoid coupling.

Sure, you could say that both 'Jungle' and 'SpaceStation' are duplicating logic, but it's simply association logic at this point, nothing that prevents bananas and gorillas to live happily apart from each other. Furthermore, it's highly likely that as the these classes evolve they may handle removal of bananas very differently, for instance, in the space station it will need to be disposed into the void, and in the jungle the disposed banana may be used to fertilize the soil.




Why is changing an integer to a class an improvement? Isn't that like my last example where every tiny thing is encapsulated by a class?

>and play with them if you desire, without an aggregation class managing them.

This is my point. Within a class you have several entities that are managed by the class. I'm saying take away the management layer all together. Take away classes which is exactly what you said.

You say you can do this:

      List<Banana> bananas;
      List<Gorilla> gorrillas;

      removeBanana(banana):
         bananas.remove(banana); 
but you can simplify even further and take away the concept of classes all together.:

      int bananas;
      int gorrillas;

      void removeBanana(int& bananas):
         bananas --;
This isn't my point though. The point is in your designs you can never expect your methods to be defined like that.

What if for the space station but not jungle... if you remove a banana you have to remove a gorilla too? What do you do? You edit the space station method to account for that. Suddenly the house class requires this too. How do you account for that in the house without copying your logic? How do you account for that without refactoring SpaceStation? Refactoring is simple in these cases but more often then not OOP causes situations where the dependencies are much more tangled and complex.

Only if removeBananaAndGorrila(int& banana, int& gorilla) was already written outside the context of a class will you be able to reuse the concept and share it between two classes. So Why not remove the concept of classes all together? That way whenever something needs it, anything can use it.

Not to mention that your style requires something called dependency injection which greatly complicates code.

removeBanana in all OOP cases can never be reused outside of a class. You must always be redefining it and wrapping banana.remove. You can fix by taking this definition outside the context of the original class with a super class (inheritance) or you can just define it outside of a class all together with no restrictions. Why restrict the ability to reuse something? This is all a class does. Better to let the type parameters of a function to restrict usage.


> Why is changing an integer to a class an improvement?

Sorry, I should have said "extend" instead of "improve" which would have better captured my intent. My bad.

> Within a class you have several entities that are managed by the class. I'm saying take away the management layer all together.

This is a central point in our disagreement, we have different strategies for handling this kind of business logic. From my OOP background I'm more comfortable abstracting the management logic required for running a jungle in a 'Jungle' class, which is the whole point of OOP. You prefer another approach, and that's all right.

> if you remove a banana you have to remove a gorilla too? What do you do? You edit the space station method to account for that.

Yes, if you have a requirement that in Space Stations the number of Gorillas should be proportional to the number of Bananas, you implement that specific behavior in the Space Station class.

> Suddenly the house class requires this too. How do you account for that in the house without copying your logic?

Ok, if more classes have the same requirement maybe it's not a specific behavior, but another abstraction, which could potentially be extract into a new component, mixin or an utility class.

> So Why not remove the concept of classes all together?

It's a design choice. I feel that OOP, when used properly, allows me to manage complex abstractions more easily.

> Not to mention that your style requires something called dependency injection which greatly complicates code.

Indeed, it requires dependency injection, along with all of the other SOLID [1] principles. But from my point of view it helps to manage and reduce complexity, not increase it, and I have even written about it in my blog [2] :)

> Why restrict the ability to reuse something? This is all a class does

Classes are intended to encapsulate behavior/knowledge, not to restrict the ability to reuse something. Even though you bring valid points to the conversation, I think you have a few misconceptions about the objectives of OOP. Here's another article I wrote describing what I believe to be the fundamental concept of OOP [3]

Lastly, I'm not here saying that OOP is better than Functional Programming. They are different things, both valid in their own domain (and also combined together in the case of OOP, which benefits from borrowing a few concepts from Functional Programming).

[1] https://en.wikipedia.org/wiki/SOLID

[2] https://thomasvilhena.com/2019/07/integrating-third-party-mo...

[3] https://thomasvilhena.com/2020/03/a-strategy-for-effective-s...




Consider applying for YC's Fall 2025 batch! Applications are open till Aug 4

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: