5 ms·
One of my dear colleagues a few years ago went on a tear and added interfaces to basically every single class he could lay his hands on. C/C++ header style I im
by rho4 6y ago
One of my dear colleagues a few years ago went on a tear and added interfaces to basically every single class he could lay his hands on. C/C++ header style I imagine. To this day I cannot easily follow code because any time I Ctrl+Click on a method call I end up stuck in the interface and have to first find the single implementing class, open it and then navigate to the corresponding method.
- alanfranz 6y ago> have to first find the single implementing class This _can_ be a problem with Java, admittedly. Sometimes you've got a single meaningful implementation, but you need an interface either for using it with services that implement such interface at runtime to create proxies (e.g. Spring, Hibernate, others) that augment its functionality, or to properly mock a dependency. BUT: the IDE should be your friend. Almost every Java IDE supports "go to the implementation". And, what is the alternative? Fewer interfaces sometimes lead to even worse patterns (for testing: monkeypatching and concrete class subclassing). I prefer the clarity of declaring an interface wherever an interface makes sense. Using a lot of interfaces and defining APIs (which are, mostly, collections of related interfaces) makes the Java ecosystem highly pluggable. I can mix-and-match a lot of different libraries and/or implementations, as long as there's an interface they can work together in a rather good fashion. Consider Python: there're very few (and sometimes poorly defined) interfaces and API; so, quite often you need to pick a library/framework which implements everything and works poorly with other implementations.
- arkh 6y ago> I can mix-and-match a lot of different libraries and/or implementations, as long as there's an interface they can work together in a rather good fashion. But are you writing a library? If not, your product does not have to be plugable. Also if you end with multiple interfaces with only one implementation you should start with classes and extract interfaces when needed. And I think the Java abstraction root problem comes from the way of doing "unit-testing" at the class level. Your users don't care about your application architecture: they want functionalities. Method and class level unit testing is just fossilizing your code and giving you some kind of feel-good number. You should be able to drop all your code, start anew with a new stack and have your tests still usable. Refactoring should never mean having to rewrite tests.
- corty 6y agoImho, organizing code in a braindead way (like single-implementation-interfaces) just to be able to test it is one of the main problems of bad code and bad languages. You make your code harder to understand, more convoluted and less refactorable. The far better approach is to seek out side-effects and state and organize your code like you would in functional languages like Haskell. Then testing is just adding a) testing all the stateless, functional and stateful stuff by pushing through prepared test objects and b) testing the side-effectful stuff through mocked side-effects or a test-mode (which you need anyways for integration tests). Cleaner, faster, easier to understand, easier to reason about. Only problem is that Java is relatively bad to use in a fuctional style.
- alanfranz 6y ago> But are you writing a library? If not, your product does not have to be plugable. I'm not writing a libraries, but other people are. In Java I can pick my IoC container, my ORM, my web stack, as I wish. I can hook-in web-related functionalities through the servlet API filters. If I pick Django in Python I get a builtin ORM and web stack. Everything is within Django, for Django; extensions are Django-specific.
- alanfranz 6y ago> You should be able to drop all your code start anew with a new stack and have your tests still usable In order for that to work, you'll need your interfaces to be stable. It's impossible otherwise :-)
- arkh 6y agoAnd what kind of interface do your app have? I'd guess a graphical one or some network endpoints. You should not test code. You should test functionalities. You should be able to rewrite all your app in a new language and still be confident your tests will tell you if something broke. "Unit testing" at the class level won't do that.
- alanfranz 6y ago
- dutchmartin 6y agoThis is hard to work with indeed. But if you eventually want to change program behavior, you just build a class that implements a specific interface and change a config file.
- tester34 6y ago> Ctrl+Click on a method call I end up stuck in the interface and have to first find the single implementing class, open it and then navigate to the corresponding method. maybe it's a weakness of an IDE?
- saberdancer 6y agoThere is a shortcut that allows you to navigate to the implementation. I know there is one in Eclipse. I'm working on some legacy code where they implemented everything in this fashion (even though 99% interfaces have only single implementation and never will have anything else). This shortcut makes the work manageable. I don't remember how it is done exactly (it's in my muscle memory), but I think ctrl and hover over shows up a mini dropdown where you can click on what you want to navigate to.
- jmchuster 6y agoThat's something the IDE should handle for you, to pass-through when there's only a single implementation.
- mtzet 6y agoI don't know any C++ IDE capable of doing this. Do you have any in mind?
- watwut 6y agoIn Eclipse, if you highlight the method call, you can press "ctrl-t" or "ctrl-t ctrl-t" to get list of implementations. I am 100% sure Idea have some solution too.
- LgWoodenBadger 6y agoIntellij IDEA - Navigate -> Implementations. Works on interfaces/classes as well as methods.
- chrisseaton 6y agoHave you tried using an IDE? This will normally let you go to the implementation of a method rather than the interface for it.
- tester34 6y agowhich one?
- chrisseaton 6y agoIntelliJ IDEA, Eclipse, etc. I'm sure any non-trivial Java IDE does this.
- UweSchmidt 6y agoIf the language+IDE combination doesn't allow for a convenient "Ctrl+Click" through the code, then there's a problem. Interfaces, Annotations, "Common" Projects and config files with important constants that are being read at runtime are a form of obfuscation. We need to be able to bring that up at code review and put it into the style guide.
- watwut 6y agoIn eclipse, you can do "ctrl-t" or "ctrl-t ctrl-t" to find implementations. You can also refactor it back.