I am currently being radicalised against OOP because of one specific senior in my team that uses it relentlessly, no matter the problem domain. I recognise there are problems where OOP is a good abstraction, but there are so many places where it isn't.

I suspect many OOP haters have experienced what I'm currently experiencing, stateful objects for handing calculations that should be stateless, a confusing bag of methods that are sometimes hidden behind getters so you can't even easily tell where the computation is happening, etc

You could write crappy code in any language. I don't think it's specific for Java. Overall I think java is pretty good, especially for big code bases.

But there's a real difference how easy it is to write crappy code in a language. In regards to java that'd be, for example, nullability, or mutability. Kotlin, in comparison, makes those explicit and eliminates some pain points. You'd have to go out of your way and make your code actively worse for it to be on the same level as the same java code.

And then there's a reason they're teaching the "functional core, imperative shell" pattern.

On the other hand, Java's tooling for correctly refactoring at scale is pretty impressive: using IntelliJ, it's pretty tractable to unwind quite a few messes using automatic tools in a way that's hard to match in many languages that are often considered better.

I agree with your point, and I want to second C# and JetBrains Rider here. Whatever refactoring you can with Java in JetBrains IntelliJ, you can do the same with C#/Rider. I have worked on multiple code bases in my career that were 100sK lines of Java and/or C#. Having a great IDE experience was simply a miracle.

The language Kotlin is actually developed by JetBrains

I've found that IntelliJ's refactorings don't work as well for Kotlin as Java but, also, I've avoided Kotlin because I don't like it very much.

You gotta admit, though, that a language which strongarms you into writing classes with hidden state and then extending and composing them endlessly is kinda pushing you in that direction.

It’s certainly possible to write good code in Java but it does still lend itself to abuse by the kind of person that treated Design Patterns as a Bible.

>kind of person that treated Design Patterns as a Bible

I have a vague idea of what the Bible says, but I have my favorite parts that I sometimes get loud about. Specifically, please think really hard before making a Singleton, and then don't do it.

Singletons are so useful in single threaded node land. Configuration objects, DB connection objects that have connection pooling behind them, even my LLM connection is accessed via a Singleton.

OK yeah that's a pretty good general principle. You think you only need one of these? Are you absolutely certain? You SURE? Wrong, you now need two. Or three.

A singleton is more than just, "I only need one of these," it is more of a pattern of "I need there to be only one of these," which is subtly different and much more annoying.

Separation of data and algorithm is so useful. I can't really comment on how your senior is doing it, but in the area of numeric calculations, making numbers know anything about their calcs is a Bad Idea. Even associations with their units or other metadata should be loose. Functional programming provides such a useful intellectual toolkit even if you program in Java.

Sorry to learn, hope you don't get scar tissue from it.

Not sure how many people are writing programs with lots of numeric calculations.

Most programs in my experience are about manipulating records: retrieve something from a database, manipulate it a bit (change values), update it back.

Over here OOP do a good job - you create the data structures that you need to manipulate, but create the exact interface to effect the changes in a way that respect the domain rules.

I do get that this isn't every domain out there and _no size fits all_, but I don't get the OP complaints.

I currently think that most of the anger about OOP is either related to bad practices (overusing) or to lack of knowledge from newcomers. OOP is a tool like any other and can be used wrong.

Creating good reusable abstractions is not easy. It's quite possible to create tarballs of unusuable or overwrought abstractions. That is less of a knock on OOP and more a knock on the developers.

But that is what classes does, it lets you have data lists and dictionaries implemented as a class so that your algorithm doesn't have to understand how the data structure is implemented. In functional programming the algorithm has to be aware of the data structure, I feel that is much worse.

> I recognise there are problems where OOP is a good abstraction, but there are so many places where it isn't.

Exactly. This is the way to think about it, imo. One of those places is GUI frameworks, I think, and there I am fine doing OOP, because I don't have a better idea how to get things done, and most GUI frameworks/toolkits/whatever are designed in an OOP way anyway. Other places I just try to go functional.

I agree. Neither OOP nor functional programming should be treated as a religion or as a paradigm that one must either be fully invested in or not.

OOP is a collection of ideas about how to write code. We should use those ideas when they are useful and ignore them when they are not.

But many people don't want to put in the critical thinking required to do that, so instead they hide behind the shield of "SOLIDD principles" and "best practice" to justify their bad code (not knocking on SOLIDD principles, it's just that people use it to justify making things object oriented when they shouldn't be).