7 ms·
> And most devs hating on Java are using an IDE written mainly in Java (all the JetBrains ones): the irony of that one gives me the giggles. Guilty as charged!
by josephg 3y ago
> And most devs hating on Java are using an IDE written mainly in Java (all the JetBrains ones): the irony of that one gives me the giggles.
Guilty as charged! I hate using Java because everything written in java seems to blend into the same indistinguishable swamp of classes with meaningless names, full of methods that constantly find new and interesting ways to obscure what your program is actually trying to do. Debugging very large Java codebases feels like living through Terry Gilliam's 1985 film Brazil.
I think the problem is cultural, not technological. It seems like there's a lot of people in the Java community who still think OO is a great idea. Who think Bob Martin's awful, muddled code examples in Clean Code are something to aspire towards. People who claim the path of enlightenment requires them to replace concrete classes with interfaces - even when those interfaces only have 1 implementation.
Anyone who writes class names like FactoryBuilderFactoryImpl and claims to walk in the light is at best a scoundrel, and at worst a follower of a religion so dark we don't name it in polite company.
This is what makes IntelliJ so impressive. It takes a master craftsman to forge something beautiful from such an unholy material. VS Code pulls off the same feat on top of election. In each case I can't tell whether to be horrified or impressed! Either way, I'm a huge fan.
- winrid 3y agoI feel like if Java had immutability by default it would be such a better language to work with. It is so hard to determine what actually gets modified where in a large Java codebase.
- cies 3y agoToo bad immutability breaks the quite-ubiquitous-in-JVM-land Bean spec (and I wonder what one was smoking before drawing that spec). I think having proper sum-types with pattern matching would have also made it a much better language.
- cbm-vic-20 3y agoIt was designed when UML and tools like Rational Rose was being pushed hard by the big consulting firms on their clients as the One True Way to build Serious Business Software. JavaBeans was designed as a way to have a conventional interface that allows code components to be snapped into GUI applications. But someone thought it would be a great idea to use it everywhere else, too.
- cies 3y agoCan we all agree that the bean spec was not a good idea? No matter how old, or what other stupid ideas were fashionable back then. I cannot see how making things "beans" actually solves anything (besides maybe a slight reduction in boilerplate when (de)serializing bean-classes).
- za3faran 3y agoJava now has sum types (sealed types) with exhaustiveness checking, pattern matching for records, and more general destructuring in the works for classes.
- fian 3y agoJava has been around for a longish time. Around the early 2000's there was at least a perception that you should avoid creating too many objects as that carried performance overhead for construction and garbage collection. https://softwareengineering.stackexchange.com/questions/149563/should-we-avoid-object-creation-in-java https://softwareengineering.stackexchange.com/questions/1495... Immutable objects often require you to construct a new object to store an updated value and garbage collect the now unused previous object. So a lot of early Java code was written with mutable objects to avoid performance issues. The Java Bean spec was written in 1997: https://blog.joda.org/2014/11/the-javabeans-specification.html https://blog.joda.org/2014/11/the-javabeans-specification.ht...
- winrid 3y agoI didn't say make everything immutable. I just mean that if you want an object to be mutable, you need to say so.
- The_Colonel 3y agoBean spec is in no way mandatory. Plenty of existing code doesn't follow the bean spec. Immutable Java classes have been in vogue for many, many years.
- za3faran 3y agoJava's records are immutable.
- kelnos 3y agoAnd most shops likely aren't using a JVM new enough to use records, and it will be a while before they are able to upgrade. And even then, most 3rd-party libraries out there won't use records, because they want to be compatible with the JVMs their users use. Hell, most popular libraries available on Maven Central are compiled with JDK8, or, at best, JDK11. Aside from immutable instances, it would be nice if 'final' was the default, as well.
- marginalia_nu 3y agoOn the one hand sure. But if we're going to critique Java honestly, can't we stick to the language the way it looks today and not the way it looked nearly ten years ago? Modern Java is quite pleasant to work with. One by one the papercuts and footguns have been fixed.
- wanttocomment 3y agoSo it sounds like the fix is available with an update. What more do you want?
- dtech 3y agoAlso still extremely hard to use due to basic they are, e.g. there is no "with"-er method or syntax yet to modify existing values.
- za3faran 3y agoWithers syntax is being evaluated/designed as far as I'm aware. You can still get some good work done with records in the meantime.
- tibbydudeza 3y ago"Anyone who writes class names like FactoryBuilderFactoryImpl and claims to walk in the light is at best a scoundrel, and at worst a follower of a religion so dark we don't name it in polite company." Awesome quote ... LOL.
- itronitron 3y agoNobody writes FactoryBuilderFactoryImpl as a class name, they define an XML schema and then use a code generator to create the source files... 1/2 /s
- _ea1k 3y agoThat was the old way. Now we ask ChatGPT to generate it for us.
- cookieperson 3y agoHad me in tears lol
- davedx 3y agoBingo! I’ll never forget working for a tiny startup under an ex Google CTO in 2013 who wrote plain Java code and chose simple libraries. Saying it was a breath of fresh air is an understatement. Code is culture and culture is code.
- klibertp 3y agoDoes anybody know where I can find a good, substantiated, critique of the common Java coding patterns, including on Android? This niche is such a huge mess that simply documenting all the bad things in a single codebase (along with explanation why they're bad) took me a month. It's tiring and mentally draining to do this: every other line of code you read makes you go "Why. Please, just tell me why anybody could ever think good code should look like this". Worse yet, there's hardly a discussion to be found about these things - it's "Uncle Bob" & co and the horde of their followers all the way, no dissenters. It looks like an echo chamber so hermetic that the most basic principles like DRY or YAGNI have a hard time penetrating it. What is the most painful for me with all this, other than it being 99% self-inflicted and not caused (you could argue it's encouraged by it, but the ultimate cause is the culture) by the language, is the fact that it has infected Kotlin code. Kotlin was built to increase expressive power of the language, doing away with multiple limitations of Java and offering lots of modern-ish features on top of it. The community looks split in half: the Kotlin community tries to get the most out of Kotlin, and the Android community that does anything in their power to make Kotlin back into Java, writing code as if the limitations were still in place and new features didn't exist. I know that the churn and "production readiness" of things on Android generally favors a more conservative approach, but it's still too much. I cry tears of blood every other code review I'm forced to do. If there's a single, definitive resource that I could point my coworkers to and eventually turn it into enforced guidelines, the author can count on a serious donation from me.
- josephg 3y agoHah. I’ve spent several years writing javascript for a living. You can always tell when code was written by someone who’s arrived fresh from Java or C++. Their code is full of hundreds of lines of useless classes which can often be replaced by a few simple object literals. Unlike class instances, object literals can be easily json stringified and parsed, too! You can torture people who are like this in code review: “This isn’t idiomatic. Please rewrite this code without the class keyword”. I’ve seen people people make a face like I just had their child expelled from kindergarten. I don’t know any good resources unfortunately. I feel like we need a “motherfuckingwebsite” equivalent for this - “just use a motherfucking function”. I want to link it to whoever insisted on adding a useless TextDecoder class in javascript that you have to instantiate, instead of just calling textDecode(…, “utf8”) using a global function like the rest of the standard library. I think part of the problem is that most people who hate enterprise java just learn a different language, set their resume on fire and start over somewhere better. That’s certainly what I did. I’m writing rust at the moment, and thankfully the lack of classes and distance from the JVM seems to keep most of this nonsense out. But having all the doubters leave makes the problem within the java ecosystem worse.
- flippinburgers 3y agoI cannot dislike "clean architecture" enough.
- BigJ1211 3y agoDo you know of any well written articles of critique against OO? I've read a few against Clean Code, that actual went over the problems with the actual examples given. Nevertheless I hardly ever see good critiques against the principles themselves. I'd be interested in reading about it in more detail.
- Verdex 3y agoIn my mind there are two major issues with java/c# style OO. 1) Subclass universality isn't great for cognitive comprehension 2) Subtyping component of subclassing has no compiler enforcement Okay, for the first point, consider the universal NAND gates. You can build any circuit that uses not, or, and etc logic gates by converting it into only nand gates. This is great for manufacturing (I guess) where you can 'compile' a straightforward series of logic gates into just nand gates and then you only need to product one kind of gate in your hardware. However, imagine if you needed to program this way (say with an imaginary nand (!&) boolean operator): today || tomorrow => (today !& today) !& (tomorrow !& tomorrow) Yeah ... just rolls off the tongue. Now, subclassing (and interfacing) provides an existential (to borrow from logic) property. That is, there exists some class such that the following methods exist (and maybe there's also some default implementations spread out amongst every super class in the inheritance hierarchy, but focus on the simple case). Existential is also universal. You can use it to simulate a forall property (think generics), an or property, or an existential property. The problem is that now you're converting what would be a straightforward structure in a more fully featured language (like unions, or ADT, or Sum types, or discriminated unions) of This thing OR That thing into something much more complicated. It might be an infinite number of things which delegate logic that should exist right here into some other class someplace else where you cannot see it without difficulty or maybe cannot see it at all. Or you can just cast the super class into a sub class ... which isn't great either. Regardless, you also have to hope that nobody goes off and implements another case that shouldn't exist because subclassing is open where an OR property in something like discriminated unions is closed. Knowing you have all of the cases considered nigh impossible. Now, this is good when you straight up want an existential property. It does happen that you get a thing and then you call a method on that thing and there really are an infinite number of things that it could potentially be both now and in the future such that you want support for that behavior. However, I assert that this requires much more complicated and careful coding and isn't applicable for most of the work that ends up needing to occur. Part two is a bit more simple. When you subclass you're also declaring a subtype. The problem is that there's no compiler support or assistance to ensure that all subclasses are actually valid subtypes of the superclass. But it's a property that you get whether or not it's true. So at any point in time you can have some object where you aren't supposed to know it's actual class, but for which if you don't know it's actual class you'll end up writing incorrect code. A superficial example can be had with exception (a whole other topic that will otherwise not be covered here). Imagine a Storage class which is just a key-value store. The CloudStorage class can throw NetworkExceptions, the InMemoryStorage class can throw OutOfMemoryExeptions, and the FileStorage class can throw FileNotFoundExceptions. Code that handles just Storage doesn't know which exceptions it might have to make sure it catches. The subclass isn't necessarily a subtype. [Of course you can open up a different discussion here about the appropriate way to handle exceptions, but I hope the simplified example here makes clear what the issue is. A more complex and realistic example can be constructed to show the same issue in a way that completely bypasses exceptions.]
- another2another 3y ago'git reset' preserve us from acolytes of Uncle Bob! Clean Code makes just as much of a mess in .net land too.
- marginalia_nu 3y ago> It seems like there's a lot of people in the Java community who still think OO is a great idea If you're coding in Java, you've better think OO is a great idea. It's an object oriented language. And despite having loosely bolted on FP paradigms, that's not really going to change. Although I feel most of the criticism against OO is actually more like a critique of the FactoryBuilderFactoryImpl-style application of design patterns, which is something else and really unfashionable today in Java.
- josephg 3y ago> If you're coding in Java, you've better think OO is a great idea. It's an object oriented language. There's plenty of room in Java for nice, clean code. All "java is OO" means in practice is that your code needs to be in classes. Some things that work great in java: - Separates out value types from everything else. Value types should usually be tiny, and have public fields. They should not contain references to any other data, and any methods should be simple. ("getTempInCelcius()" is ok, "updateFromDatabase" is not.) - Express saving / loading / processing work as (ideally) pure functions which operate on that data. You can use the class keyword + static functions to make a module / namespace in java. Use it. - Use interfaces sparingly. Try not to use inheritance at all. - (Controversial): If you find yourself with 18 different classes instantiated at runtime, where all those classes have exactly 1 instance (and probably all hold references to each other), you're doing it wrong. Use fewer, larger "controller" style objects (ideally 1), arranged in a tree (no references should point up the tree). If your classes get big, move utility code out into pure functions or short lived utility classes in adjacent files. - Don't use factories. If you need to, use value types for configuration data. Is this still "OO"? Depends what you mean by OO. I've heard this style of programming referred to as "data oriented programming", or something like that. Done well, data and data processing often end up in separate files. (Which is the opposite how OO is usually done). Features can often land in separate folders. Performance usually ends up better, because you have less pointer chasing and indirection. You often get much clearer separation of concerns between classes. And its usually much easier to write unit tests for code like this - since almost all classes can be instantiated and tested directly. A lot of modern game development uses patterns like this, coded in C++. Most C code looks like this too. I've also read and written plenty of javascript / typescript which follows this pattern. Its very simple in JS/TS because you can use object literals (with interface definitions in TS) for your value types. In rust, your large "controller" style classes with a million methods can have all those methods spread out throughout different files in your project. (Ideally grouped by feature.)
- goda90 3y agoI've spent most of my programming life working in OOP. I see people critical of it, but I don't know what the alternative is for the kind of stuff I do for my job (not to say I have a choice in changing how we do it). Does anyone know of an open source project that implements a complex GUI app that doesn't use OOP so I can see what that code can look like?
- jansan 3y agoWe even use OOP in Javascript today, although capsulation is still a but sketchy and there is no support for interfaces and abstract classes. There is support for interfaces in Typescript, which was added because, well, it makes a lot of sense :)
- deleted 3y ago[deleted]
- edgyquant 3y agoAny functional react application would fit the criteria I imagine.
- arcbyte 3y agoI've seen people take Bob Martin's concepts and do some truly awful things with it. Mind-bogglingly awful contortions of concepts into classes in arrangements that have to be sourced from demonic inspiration. At the same time, I've seen the best code of my entire life formed from his concepts. Code that will last decades, far outlasting the UIs that feed it data or the databases that will store it. I think the difference is all on whether the developers who wrote it understood that the "concepts" are not meant to be put into code on a 1 for 1 basis. For example, making a AddToDoUseCasePresenterInteractor class is literally taking the concept and making it 1 to 1 in the code. On the other hand, writing domain appropriate code, minimizing accidental complexity, and recognizing the clean code concepts as emerging from groups of classes and methods and packages in a code base leads to really clean, testable, maintainable, and FAST TO WRITE code. I think the single biggest improvement for java programmers is to group all the classes related to a use case together in the same package - which means STOP MAKING "controller", "service", "model", etc packages where every different unrelated except by use is just dumped. If you're working on a part of the code base you should just have to change classes in one single folder. A new feature should just be a new folder. That change alone speeds up teams by huge factors.
- ajmurmann 3y agoYour last paragraph is really interesting to me. It obviously makes total sense. Yet, three environment I've used most in my career is Rails which also splits these things into folders by type rather than feature. It's never bothered me. Now I wonder if that because Ruby isn't Java and folders aren't packages or because I'm so very used to it.
- _ea1k 3y agoI've worked in a few codebases that tried to group things by feature. In my experience, it never really worked that well. Usually there would either be poor isolation between them or they'd be so well isolated that I'd wonder why they were even in the same project. In the latter, they'd often be difficult to maintain because of a web of dependencies pulled in by the little isolated subfeatures. I prefer the separation by type, tbh. It also has the upside that it naturally encourages the developer to follow the same patterns within that particular package.
- FpUser 3y ago>"It seems like there's a lot of people in the Java community who still think OO is a great idea." Java is not the only language in existence and the OO is a great idea as well as many other paradigms when not being overused. Problem is with the programmers who learn one language / paradigm and would fight tooth and nails to solve all world problems with it no matter how poor for particular case.
- akavi 3y agoObjects are a useful idea. Object Orientation is a terrible, terrible idea. Functions + data (immutable when practical) is all you need for 90%+ of programming, and you should only reach for objects when necessary to manage some well-encapsulated but tricky state. Your default orientation should certainly not be towards objects.
- FpUser 3y ago>"Your default orientation should certainly not be towards objects." My default orientation should be what my experience tells me is the best for particular case.
- josephg 3y agoYou should trust your judgement. But good judgement comes from experience. Anyone who only has experience programming in one language, or one style, will have rubbish judgement. Go learn Haskell, OCaml or Rust. Write some C for embedded platforms. Make a video game using your own hand spun ECS in C++. If, after all that, you come back and say "yeah lets use a class here", then I'll trust your judgement.
- FpUser 3y agoI am paid for designing and implementing products. Language for me is a screwdriver. Some convenient some not that much. I have programmed in many languages. I am familiar with the concepts but not going to learn OCaml or Haskel as there is zero ROI in it for me. >"If, after all that, you come back and say "yeah lets use a class here", then I'll trust your judgement." Look at it this way. I care what my customers say about my products because this is how I make my money for decades already. You - trusting my judgement - I do not give a flying fuck. Sorry for being direct.
- dep_b 3y ago> Anyone who writes class names like FactoryBuilderFactoryImpl and claims to walk in the light is at best a scoundrel, and at worst a follower of a religion so dark we don't name it in polite company. I have to say I already expected the comments to be good when I read the title but this nugget of pure gold - I would PAY to read comments like this!
- ff317 3y agoSomeone has to link this here, so it may as well be me :) https://steve-yegge.blogspot.com/2006/03/execution-in-kingdom-of-nouns.html https://steve-yegge.blogspot.com/2006/03/execution-in-kingdo...
- denton-scratch 3y ago> I think the problem is cultural, not technological. I'm sure that's true. You don't have to write classes with names like DoubleFactoryFactory; nobody does that in other languages. It's a tribal thing. What's amusing (to me) is that Java isn't actually object-oriented, because many of the core datatypes aren't objects.
- ravenstine 3y ago> Guilty as charged! I hate using Java because everything written in java seems to blend into the same indistinguishable swamp of classes with meaningless names, full of methods that constantly find new and interesting ways to obscure what your program is actually trying to do. Debugging very large Java codebases feels like living through Terry Gilliam's 1985 film Brazil. That describes just about every codebase I've worked with that relies on object-oriented patterns, which is basically every codebase. This is particularly bad with Java, but as you mentioned, this is a cultural problem and not so much a language problem. I like Java the language, but what kept me away from it was every Java codebase I've seen. Layers upon layers of needless abstraction, overly abstract names, and so much code is meant to describe things rather than a sequence of data changing. It's not that OO is completely wrong, but it's a meme that we as programmers are refusing to shake. It's like people are still getting taught OO in college courses by programmers who haven't worked professionally in decades, and those students are still going into the real world thinking that everything's gotta be object oriented. And usually what OO ends up meaning is having classes and inheritance and "this" and mutability, as opposed to having objects that pass each other information. The latter doesn't need classes, or inheritance, or any of the other similar features in programming languages. But if you've got to write to a file, then you've gotta make a class that wraps the file system functions, right? /s
- tracker1 3y agoI have similar feelings on the .Net space as well. It's not the language (C#) or the platform so much as the "Enterprise" community.