Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

I rarely see inheritance used in practice in java code bases. Except where I would use a union type or sealed class in other languages anyways. I don't feel what youre describing is a real issue.


You must be really lucky then. In my previous job, inheritance and abstract classes were everywhere. Coupled with dependency injection frameworks that "worked like magic", it was really hard to follow the code inside that big, monolithic app. It made me never want to work with Java ever again.


I've never been a big fan of dependency injection. It solves a problem with unit testing in Java, sure, but the reality is that Java could have done some nifty things to help alleviate that as well.


Agreed. Java injection frameworks are opaque and accomplish what they need to with overly powerful mechanisms because of the nature of the language. You don't see that sort of nonsense in python.


Wtf, so what do you think Django is?


I'm curious to understand what dependency injection is in Django that you're referring to?

I know pytest does DI with fixtures, and trying to figure out what you're pulling into a test can be difficult.


In django you're importing a default cache, a default storage etc, and write your code to the interface. In settings.py you wire it all up. It's basically the same, for testing you would have to mock the import or provide some implementation.


technically that's not dependency injection, but a global service locator.


Yeah I agree on that here.

The user doesn't write DI code for Django Class Based views. E.g. the view doesn't accept a Database upon instantiation.


Nothing to do with the nature of the language, but with the nature of the program.

If you're writing a few line script, you don't need a DI container. Once your program gets large, it becomes extremely messy without one. It's no surprise projects like [1] exist.

[1] https://github.com/ets-labs/python-dependency-injector


That DI library is not pythonic at all.

There's nothing wrong with this at all, say:

    class MyClass:

        def __init__(self, my_dep1=None):
             if my_dep1 is None:
                 self.my_dep1 = get_my_dep1()  # Or potentially raise
             else:
                 self.my_dep1 = my_dep1

             [...]

Then to test:

    def test_my_class(): 
        mocked_dep1 = MagicMock()
        my_class = MyClass(my_dep1=mocked_dep1)
        [...]


And if you want to configure the scope of `my_dep1` (singleton, transient, etc.)? What about nested dependencies? etc.


Why do I care about any of that while writing python? Those seem like artifacts of a Java based DI system.


It's a reality of any non-trivial program, regardless of the language.


No. Some languages don't require you to play cat and mouse games to get around artificial limitations put there by the language designers.

There was a talk at PyCon a while back about that patterns commonly used in Java were non-existent in Python.


If that’s the only thing it’s used for in the project, then you are most likely good with Autowired (in Sping) or something similar.

Any complicated DI solution must have a reason for it being there and I’ve seen too many projects complicating themselves on buzzwords like DI or MSOA without really needing either that much


Sounds like you’re confusing DI with DI containers.


I've seen the same craziness with NodeJS, and very simple Java services with minimal inheritance.


Inheritance used to be extremely common, look at AWT/Swing - however more or less it finished there, e.g. more than 20y back.

There are still lots of folks who love 'protected' and deep hierarchies, of course. There is stuff like spring that uses way too many interfaces with a single implementation, doing something a bit off the regular road ends up implementing tons of the said interfaces anew.

However the 'hate' part is mostly the internet (well esp. Hacker news)warrior topic


Great to hear. I used to program java in 2010 and inheritance was still beeing heavily used back then. But things change, if both the lang and the main community has change to focus more on simplicity its def worth looking at again. Coroutines and pattern matching is really good features


Contrast that, I've seen numerous Java codebases, young and old, and inheritance is very much one of the core ways that people program.

I strongly suspect that in a few cases some Java devs using net new systems and avoiding common frameworks will perhaps be able to avoid lots of inheritance but I find it insane to say that that's common or even easy.


Inheritance is heavily used in Java in 2023, at least in projects I’ve had to look at.


> I rarely see inheritance used in practice in java code bases.

That seems absurd to me and I have a hard time understanding it, honestly.


> I rarely see inheritance used in practice in java code bases.

Without some specific call-out, it can be assumed that this is a very niche viewpoint that has no bearing on modern development.

The vast majority of projects use inheritance, today.

Does it use Spring? extends SpringBootServletInitializer

Meaningful responses using values from a request? extends OncePerRequestFilter

Formatting exception handling responses on web requests? extends ResponseEntityExceptionHandler

Then there's all the interfaces you have to satisfy, because it's all tied into the standard library and popular libraries.


You need to inherit to create anything that is a class. But the focus is on composition. You inherit from useful classes so you can build the solution using composition.

I don’t like modern Java because there’s too much non-Java magic code. Layers of stuff that “helps” but removes me from the language. Entire programs written in config and special text wrapping classes and methods. How it works requires understanding multiple intersecting languages that happen to be strung together in .java files.

Edit: when something is in config it’s not checked at compilation. Every environment from dev to prod can have its own config so when you compile in dev you don’t know what’ll happen in prod. I know: let’s add more tools and layers.


> You need to inherit to create anything that is a class

That's true of the Java compiler, for which the documentation is strewn around the intenet...but an example is here: https://medium.com/javarevisited/compiler-generated-classes-...

The Java syntax doe not require extending Object explicitly.eg This is a valid, useless, class:

    public class App {}
> I don’t like modern Java because there’s too much non-Java magic code

It seems like this is the common path for popular languages. They develop their own library-backed DSL's for the most common use cases, which are often little more than macros (@data @getter, @notnull, etc). I am biased by what I've seen in the last 30 years though.


The OP/GP wasn't really complaining about inheritance, despite the fact that this is what they wrote.

The OP is complaining about the difficulty of the API because it is _exposed_ through inheritance.

The complaint about `SpringBootServletInitializer`, for example, is exactly this. There's nothing wrong with inheritance. In fact, SpringBootServletInitializer is exactly what you want to use inheritance for - because you need to build your app using the servlet api.

There are http servers that aren't servlet api, such as https://vertx.io/docs/vertx-web/java/#_re_cap_on_vert_x_core... , which uses little to no inheritance (since the api surface is smaller).


Having a single level of inheritance (especially if it's an interface) is not a problem at all. Having deep inheritance trees can be a code smell.


While you have to extend some things in Spring, yes, the whole point of the DI in spring is so that you can often compose instead of extend.


If you type everything with interfaces in your codebase, you are much less tied to inheritance. In fact, everyone could be written to be composed.

However Java doesn’t support type union so you can get into some ugly and verbose situations but the JVM doesn’t really check type so this is more a compile-time issue and could be fixed in a future Java language revision.


>However Java doesn’t support type union so you can get into some ugly and verbose situations

Isn't the "sealed interface" described in the OP blog post a type union? Or you mean anonymous unions?


Definitely referring to anonymous unions too. Without them, there’s still friction sometimes which makes union types unnatural.

I haven’t written Java in a while and I can’t remember if you could sometimes fake a type union using a generic type on a method, but if you can, it’s definitely super ugly and would raise eyebrows during any code review.


Anonymous unions are a relatively rare feature; Rust and Haskell don't have them, for instance.


Sorry, what? Is not java toghether with Ruby maybe the most hardcore OOP enthusiasts that uses inheritance for "most stuff".

Has the java culture move so far the last decade ?


Effective Java, written by Joshua Bloch, and first published in 2001, had a very influential section called Favor composition over inheritance:

https://books.google.co.nz/books?id=Ra9QAAAAMAAJ&q=inheritan...

Why do you think DI is so prevalent in Java codebases? It's a great way of simplifying composition.


>had a very influential section called Favor composition over inheritance

The GoF book (Design Patterns) had the same, somewhere early, like in the Introduction, in 1994:

https://en.m.wikipedia.org/wiki/Design_Patterns


I’ve been writing OOP code and reading about it for a decade or two, and inheritance was identified as problematic pretty quickly. The problem today, imo, is more underuse now.


>inheritance was identified as problematic pretty quickly

Exactly what I referred to here:

https://news.ycombinator.com/item?id=37539443


Yeah, it’s a bit like how the school version of lisp makes people think real lisp code bases are all lists and recursion.


Funnily enough, it actually started from C++. And, Java is so large that it is simply meaningless to talk about a unified style -- sure, some Java EE behemoth will continue to run on a complicated Application Server for decades still, churning on its workload, but so will someone write a Micronaut microservice, or something for robotics, and these will all have distinct styles.

With that said, even the Java EE/Spring complicated word has been moving towards a less inheritance-based future.


Even in Ruby, IME, deep inheritance is fairly uncommon.

Wide inheritance through mixins is common, though.


HtmlElement. AST. Socket. Stream. Window. Closable. Runnable.


Your Point?

Long:

Please make your Point Understandable.


Examples of classes where inheritance is indispensable. I cannot imagine what kind of programming you are doing where that pattern never comes up.




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

Search: