5 ms·
> 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
by 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> You should not test code. You should test functionalities. You're talking about integration tests and/or end-to-end tests. I write those. Usually at the façade level, not at the network endpoint (which usually means the controller level, a shallow layer that often includes some ACL and serialization) but it's just a matter of taste. > 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. Unit tests, integration tests and e2e tests are different things that solve different concerns. An e2e test will rarely expose an obscure bug within an implementation, and a unit test will rarely expose concerns in the global application flow. Both have their place. And they have nothing to do with the "interface vs not interface", IMHO.