5 ms·
For me, it's the fact that the mess of DAOs and Factories that constituted "enterprise" Java in the 00s was a special kind of hellscape that was actively encour
by mywittyname 1y ago
For me, it's the fact that the mess of DAOs and Factories that constituted "enterprise" Java in the 00s was a special kind of hellscape that was actively encouraged by the design of the language.
Most code bases don't need dynamically loaded objects designed with interfaces that can be swapped out. In fact, that functionality is nearly never useful. But that's how most people wrote Java code.
It was terrible and taught me to avoid applying for jobs that used Java.
I like OOP and often use it. But mostly just as an encapsulation of functionality, and I never use interfaces or the like.
- Nursie 1y agoThankfully those days are not with us any more. Java has moved on quite considerably in the last few years. I think people are still too ready to use massive, hulking frameworks for every little thing, of course, but the worst of the 'enterprise' stuff seems to have been banished.
- zelphirkalt 1y agoI hope you are right. I really do. But I have a hunch, that if I accepted any Java job, I would simply have coworkers, who are still stuck with "enterprise" Java ideology, and whose word has more weight than the word of a newcomer. That's one of the fears, that stops me from seriously considering Java shops. Fear of unreasonable coworkers and then being forced to deliver shitty work, that meets their idea of how the code should be written in the most enterprise way they can come up with. Always makes me think of that AbstractProxyFactorySomething or similar, that I saw in Keycloak, for when you want to implement your own password quality criteria. When you step back a bit and think about what you actually want to have, you realize, that actually all you want is a function, that takes as input a string, and gives as output a boolean, depending on whether the password is strong enough, or fulfills all criteria. Maybe you want to output a list of unmet criteria, if you want to make it complex. But no, it's AbstractProxyFactorySomething.
- throwaway2037 1y agoI don't understand these complaints. Here is a tiny interface that will do what you need: @FunctionalInterface public interface IPasswordChecker { bool isValid(String password); } Now you can trivially declare a lambda that implements the interface. Example: const IPasswordChecker passwordChecker = (String password) -> password.length() >= 16;
- abrenuntio 1y agoI'm personally rather fond of Java, but even this (or the shorter `Predicate`) still can't compete with the straightforward simplicity of a type along the lines of `string -> bool`.
- throwaway2037 1y agoI bet you are the kind of person who uses "auto" a lot in whatever programming language that you use. For me, context matters because, in the words of Joel Spolsky, (1) you read code much more than you write code, and (2) it is harder to read code than write code. As a result, I always choose the more verbose form when writing code that other people will read.
- deleted 1y ago[deleted]
- jjmarr 1y agoIt's very useful in C++, funnily enough. This is because I can have a non-templated interface base class, then a templated impl class. Then my templated impl header can be very heavy without killing my build times since only the interface base class is #included. Not sure if this is as common in Java.
- vasvir 1y agoJava uses type erasure which are very cheap in compile time but you cannot do things like t = new T(); // T is a template parameter class C++ uses reified generics which are heavy on compile time but allows the above.
- mattashii 1y agoThat's why they're called generic parameters, not template parameters; the code is generic over all possible parameters, not templated for every possible parameter.
- throwaway2037 1y ago> C++ uses reified generics I was a C++ programmer for many years, but I never heard this claim. I asked Google AI and it disagees. > does c++ have reified generics? > C++ templates do not provide reified generics in the same sense as languages like C# or Java (to a limited extent). Reified generics mean that the type information of generic parameters is available and accessible at runtime.
- dcow 1y agoInteresting I’d never picked up on this pedantic subtlety. I too thought reified meant what you could do at the call site not what you could do at runtime. Was my understanding wrong, or is Gemini hallucinating. In any event, you have to use weird (I think “unsafe”) reflection tricks to get the type info back at runtime in Java. To the point where it makes you think it’s not supported by the language design but rather a clever accident that someone figured out how to abuse.
- 1y ago
- locknitpicker 1y ago> Most code bases don't need dynamically loaded objects designed with interfaces that can be swapped out. In fact, that functionality is nearly never useful. But that's how most people wrote Java code. Perhaps I'm not following, but dynamically loaded objects are the core feature of shared libraries. Among it's purposes, it allows code to be reused and even updated without having to recompile the project. That's pretty useful. Interfaces are also very important. They allow your components to be testable and mockable. You cannot have quality software without these basic testing techniques. Also, interfaces are extremely important to allow your components to be easily replaced even at runtime. Perhaps you haven't had the opportunity to experience the advantages of using these techniques, or were you mindful of when you benefited from them. We tend to remember the bad parts and assume the good parts are a given. But personal tastes don't refute the value and usefulness of features you never learned to appreciate.
- athrowaway3z 1y agoWe're talking about OO Java. You bring up shared libraries, list a bunch of things not unique to Java nor OO, then claim `etc.` benefits. You really haven't argued anything, so ending on a "you must be personally blind jab" just looks dumb.
- mike_hearn 1y agoIt's because the concepts are the same, but people get enraged by the words. What Java calls a factory would be a "plugin loader" in C++. It's the same concept. And most big C++ codebases end up inventing something similar. Windows heavily uses COM which is full of interfaces and factories, but it isn't anything to do with Java. Java I think gets attacked this way because a lot of developers, especially in the early 2000s, were entering the industry only familiar with scripting languages they'd used for personal hobby projects, and then Java was the first time they encountered languages and projects that involved hundreds of developers. Scripting codebases didn't define interfaces or types for anything even though that limits your project scalability, unit testing was often kinda just missing or very superficial, and there was an ambient assumption that all dependencies are open source and last forever whilst the apps themselves are throwaway. The Java ecosystem quickly evolved into the enterprise server space and came to make very different assumptions, like: • Projects last a long time, may churn through thousands of developers over their lifetimes and are used in big mission critical use cases. • Therefore it's better to impose some rules up front and benefit from the discipline later. • Dependencies are rare things that create supplier risks, you purchase them at least some of the time, they exist in a competitive market, and they can be transient, e.g. your MQ vendor may go under or be outcompeted by a better one. In turn that means standardized interfaces are useful. So the Java community focused on standardizing interfaces to big chunky dependencies like relational databases, message queuing engines, app servers and ORMs, whereas the scripting language communities just said YOLO and anyway why would you ever want more than MySQL? Very different sets of assumptions lead to different styles of coding. And yes it means Java can seem more abstract. You don't send queries to a PostgreSQL or MySQL object, you send it to an abstract Connection which represents standardized functionality, then if you want to use DB specific features you can unwrap it to a vendor specific interface. It makes things easier to port.
- pjmlp 1y agoAs someone coding since 1986 it is always kind of interesting how Java gets the hate for something that it never started, and was already common in the industry even before Oak became an idea. To the point that there are people that will assert the GoF book, published before Java was invented, actually contains Java in it.
- zelphirkalt 1y agoIt is probably because Java took this design philosophy (or I should say dogma) to heart as its very syntax and structure encourages to write code like that. One example: It does not have proper modules. Modules, the one thing that most people can agree upon that are a good thing, enabling modularity, literally. Another one: You cannot have simply a function in a module. Shit needs to be inside classes or mixed up with other unrelated concepts. Java the language encourages this kind of madness.
- pjmlp 1y agoIt is called packages. There is nothing on the modules as programming concept that requires the existence of functions as entity. Again, Smalltalk did it first, and is actually one of the languages on the famous GoF book, used to create all the OOP patterns people complain about, the other being C++.
- Supermancho 1y agoIn java, it has to be a class in a package. Packages are sane enough. That isnt the point.
- pjmlp 1y agoThat is the point, packages the Java programming language feature for the CS concept of modules. https://en.wikipedia.org/wiki/Modular_programming https://en.wikipedia.org/wiki/Modular_programming > Languages that formally support the module concept include Ada, ALGOL, BlitzMax, C++, C#, Clojure, COBOL, Common Lisp, D, Dart, eC, Erlang, Elixir, Elm, F, F#, Fortran, Go, Haskell, IBM/360 Assembler, IBM System/38 and AS/400 Control Language (CL), IBM RPG, Java, Julia, MATLAB, ML, Modula, Modula-2, Modula-3, Morpho, NEWP, Oberon, Oberon-2, Objective-C, OCaml, several Pascal derivatives (Component Pascal, Object Pascal, Turbo Pascal, UCSD Pascal), Perl, PHP, PL/I, PureBasic, Python, R, Ruby,[4] Rust, JavaScript,[5] Visual Basic (.NET) and WebDNA. If the whole complaint is that you cannot have a bare bones function outside of a class, Java is not alone. Predating Java by several decades, Smalltalk, StrongTalk, SELF, Eiffel, Sather, BETA. And naturally lets not forget C#, that came after Java.
- throwaway2037 1y ago> that was actively encouraged by the design of the language. Java hasn't changed that much since the "hellscape" 00s. Is it better now? Or what is specific to the language the encourages "the mess of DAOs and Factories"? You can make all of those same mistakes in Python, C# or C++. I have used Java for about 15 years now and I have never written any of that junky enterprise crap with a million layers of OO. > I never use interfaces or the like. This is the first that I heard any disdain towards interfaces. What is there not to like?
- trillic 1y agoIt insists upon itself. That’s really the problem with Java’s design philosophy from that era; it encourages ceremony. Even if you don’t write the full-on "Enterprise™" soup of DAOs, Factories, and ServiceLocators, the language’s type system and conventions gently nudge you toward abstraction layers you don’t actually need. Interfaces for everything, abstract classes “just in case,” dependency injection frameworks that exist mainly to manage all the interfaces. Java (and often Enterprise C#) is all scaffolding built to appease the compiler and the ideology of “extensibility” before there’s any actual complexity to extend. You can write clean, functional, concise Java today, especially with records, pattern matching, and lambdas, but the culture around the language was forged in a time when verbosity was king.
- LandR 1y ago"But but... I can swap out my entire my persistance layer since it's all just an interface!" Has anyone ever actually done this ?
- marcosdumay 1y agoI have used something similar with effects in Haskell to mock "the real world" for running tests. But if it was as convoluted to use as it's in Java, I wouldn't. And also, it's not enterprise CRUD. Enterprise CRUD resists complex architectures like nothing else.
- throwuxiytayq 1y agoFunny, given that interfaces are the good part (especially compared to inheritance).
- mywittyname 1y agoI didn't mean to imply that interfaces are bad or useless. Just that I don't use them. Probably because I write most of my stuff in Python anymore.
- dahauns 1y agoI think the best description of this kind of "obfuscation" that especially afflicted Java still is Steve Yegge's "Kingdom of Nouns" rant: https://steve-yegge.blogspot.com/2006/03/execution-in-kingdom-of-nouns.html https://steve-yegge.blogspot.com/2006/03/execution-in-kingdo...