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

A couple of examples from Java/Kotlin code:

- Too much business logic hidden behind dependency injection (using Dagger in this instance). I think DI should be used sparingly, to decouple large subsystems like the database or the network. It can feel clever to inject everything, so your system is super modular and decoupled, but that just makes it much harder to understand, with little or no real benefit.

- Somewhat related, excessive use of annotations to accomplish tasks that could be done in a more straightforward way with normal code. For example, in Android, you might have an annotation that adds some fragment to your activity as a mix-in; but is that really easier than just calling a function to do the same thing?

This stuff starts to cause real trouble when there are 1000 occurrences sprinkled through your code, and suddenly you need to step through it to debug a tricky problem. Straight-line code is vastly easier to deal with.

So I’d say “clever” is more of a problem at an architectural level, rather than inside individual functions.

At the low level, shorter is almost always better. If somebody comes up with a clever way to reduce a function from 10 lines to 4, say, that’s great -- as long as its purpose is clear and it’s testable.




Interesting examples. I am still conflicted about DI. I have seen it used too little which means that classes become basically untestable. OTOH, things like Spring (don't know about Dagger) seem so overcomplex and hard to figure out, I can certainly understand your point. I've had some luck with just hand-rolled DI in certain cases (e.g. a class that I know is mostly coordinating other classes; in that case, I might just inject all the dependencies manually for easy testing but provide a default constructor for actual production use), but I think it's hard to find the right balance.

Agreed about the annotations; it's one of the annoying things about Java, IMHO. The language itself is so inexpressive that people have to resort to annotations to do basic stuff. I think some level of "metaprogramming" can be useful (regardless of the language), either for boilerplate reduction or for removing aspects like logging from the main code, but it's too easy to become "clever" about it (not just in Java; Rubyists abuse metaprogramming way too often too, for example). I generally favour "explicit over implicit", which also means that I generally dislike inheritance because of all the non-local reasoning.


I've had some luck with just hand-rolled DI in certain cases (e.g. a class that I know is mostly coordinating other classes; in that case, I might just inject all the dependencies manually for easy testing but provide a default constructor for actual production use)

Same here! I think that approach works really well when you’re able to use it.

I’d love to try removing the DI framework and see what you get just rolling it all by hand, but that’s a tough sell in a large pre-existing project.


you could do it as a personal side project without merging it into the mainline and you might learn one of three things:

- handrolled is better and the framework stinks

- there are some disadvantages to the framework, but after doing it all by hand you also understand how it makes a lot of things easier

- it's a tradeoff that largely amounts to which kinds of problems you're personally more willing to put up with (quite likely outcome)

in any case you would learn something




Join us for AI Startup School this June 16-17 in San Francisco!

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

Search: