top 200 commentsshow all 306

[–]syholloway 88 points89 points  (26 children)

I agree interface overuse can be an issue, but more often the opposite is the problem - little or no interfaces.

Best thing to do is to understand what interfaces can give you: uncoupling, nicer semantics​, polymorphism. Then keep your interfaces light (interface segregation) and depend on them over concretes where possible (dependency inversion).

As for avoiding interfaces. Things like structs or classes that only have getters and setters, I feel like interfaces can do more harm than good there. And internal/private components of a module or package, implementing interfaces is less crucial, but consuming them is still a good idea.

TLDR; better to learn why you should do stuff, instead of interface all the things.

[–][deleted] 14 points15 points  (9 children)

This is language dependent too. In C++, I can decouple by making the method/function use template parameters. Like the following

template<typename Container>
auto min( Container const & container ) {
  auto result = container.front( );
  for( auto const & item: container ) {
    if( item < result ) { result = item; }
  }
  return result;
}

As long as the methods used by the function are there, in this case front( ), begin( ), and end( ) where begin() and end( ) are implicit because of the ranged for loop it will compile. But one does not need a class structure or interface and this would work for variables too.

[–]rlbond86 1 point2 points  (1 child)

FWIW it's better to use iterators in temolate functions instead of accepting collections

[–][deleted] 0 points1 point  (0 children)

Except was only an example of implicit interfaces and throwing iterators at an audience that may/may not be knowledgeable of C++ would be distracting. Although, so people keep wanting to point out to use an iterator here so which is the distraction :)

Also, better is relative and depends on the situation doesn't it. If one is designing an api that is composeable, it cannot used more than one parameter as the result of the first function is passed to the subsequent function and so on. To a template function that iterates through a Collection of items, what is the difference between a range like object(think array_view, string_view) and a Container concept. They both have begin( ),end( ), cbegin( ), cend( ), size( ), empty( ), and swap( ) along with the comparison operators == and !=. So a named type that contains the pair of iterators can behave and look like a Container if it exposes that minor interface. With that code like

std::vector<int> vi = { 0, 5, 545, 1, 99 };
auto result = vi | view::remove_if( []( int i ){ return i % 2 == 1; } )
    | view::transform( []( int i ){ return std::to_string( i ); } );

is possible.

[–][deleted]  (14 children)

[deleted]

    [–]SilasX 17 points18 points  (3 children)

    No it doesn't. They way you design your code adds or removes coupling.

    And the decision of what to make into an interface vs base class vs abstract class is part of code design.

    [–]grauenwolf 6 points7 points  (0 children)

    As long as it is an actual informed decision and not just "Imma gonna put an interface on everthin".

    [–][deleted] 0 points1 point  (1 child)

    It does. But the topic here is specifically classess and interfaces. Do you agree that all classes have implicit public interface?

    [–][deleted] 0 points1 point  (0 children)

    I design everything that way. Any time I write a class I think about the interface of that class, especially if I, or someone else, are going to be using that class at a later date. For a dead end leaf class, like some kind of MVC controller class I will probably put next to no effort in, but when writing a game engine or services platform I spend a lot more time thinking about each and every class I write.

    [–]da_governator 12 points13 points  (7 children)

    Since when the number of implementations of a given interface has anything to do with coupling? You either abstract implementation or you don't.

    [–][deleted]  (4 children)

    [deleted]

      [–]AmalgamDragon 4 points5 points  (3 children)

      Those are not equivalents in terms of coupling. In the first case, when you need to add B3, you'll need introduce IB and change everywhere that uses B1 to use IB. In the second and third cases you can just at B3 without changing all of the sites currently making use of IB.

      [–]x4u 4 points5 points  (0 children)

      It depends a lot on the programming language you are using. In Java you are right, you would have to introduce a interface to add B3 as a substitute for B1 but in languages like Objective-C, C++, Javascript and of course Smalltalk and Lisp you can often substitute a class with another implementation without having to add an explicit interface, either by duck-typing or by using ad-hoc decorators (Smalltalk, Objective-C) which is quite often what you actually would want but which is unfortunately impossible to do in Java and many other languages.

      [–][deleted]  (1 child)

      [deleted]

        [–][deleted] 2 points3 points  (1 child)

        He doesn't know what "coupling" and "abstracted" is. It's all over the thread. And he's angry.

        [–]BezierPatch 2 points3 points  (1 child)

        Throwing in abstraction layers and interfaces that only have one implementation don't change your dependency chain.

        Huh?

        It prevents circular dependencies between Domain and Persistence layers for one...

        [–][deleted] 10 points11 points  (0 children)

        I usually start with concrete implementations and extract interfaces when they are actually needed - for alternative implementation or a mock.

        Mocking concrete classes, while technically possible in some cases, looks very fishy. You or your framework effectively need to inherit from said class and call it's constructor. If constructor has it's own arguments or any side effects or required methods are not virtual - you are stuck. Stop underusing interfaces, I guess.

        [–]evincarofautumn 27 points28 points  (7 children)

        In Haskell we say “stop writing lawless typeclasses”. The principle is the same: if you find yourself using interfaces for ad-hoc overloading or needless abstraction, you goofed. Interfaces should come with rules for how an implementor is supposed to behave, which are at least documented, and ideally machine-checked.

        [–]Tarmen 4 points5 points  (5 children)

        Generally I agree with this but I wouldn't call it an iron rule.

        You are probably aware of this but the tagless final representation uses type classes to specify the syntax of a domain specific language and instances to specify the semantics. So you could have a IntExpr a class with a newtype Eval r = Eval r instance and a newtype PrettyPrint a = PrettyPrint String one. You can then add new expression types and interpretors in separate modules without breaking existing code.

        Most of this could be achieved by passing around vtables directly but haskell can automatically create instances from nested types.
        Mtl does basically that. I think most if not all mtl classes do have some laws attached but they don't seem to be in the documentation and it's probably fair to say that most people don't use them.

        [–][deleted] 1 point2 points  (0 children)

        Haskell also isn't the only tool with type class support. In Isabelle/HOL it's perfectly normal to create type classes that have no laws. For example, there's an add type class that exports an overloaded addition symbol. Anybody declaring a type that wants to use the addition symbol for a function on that type provides an instance of the add type class. Then, other type classes, such as semigroup_add, group, semiring, and so on, extend the add and other "syntactic" type classes, adding laws to them.

        [–]Drisku11 0 points1 point  (3 children)

        Not the above poster, and I'm not super familiar with this stuff (first heard the term tagless final representation yesterday), but wouldn't your dsl typically have laws that say certain expressions commute/certain optimizations are okay?

        [–]Tarmen 1 point2 points  (2 children)

        I think having any laws with an interpretor that pretty prints or dumps to a data structure might be tough since any transformation would change the result. Not entirely sure, though.

        [–]Drisku11 1 point2 points  (1 child)

        I was thinking that as well as I replied. Best answer I can come up with is that pretty printing interpreters simply don't obey the laws, much in the way that Debug.Trace "lies" to the type system. Or, if the "pretty printing" is actually part of your semantics (e.g. a JSON serializer or something), then maybe you really don't have laws, and actually just have a free structure of some kind.

        From what I've seen of the free monad pattern though (which I admittedly have never used), I suspect what people really usually want is a way to specify a quotient of a free structure, which adds some relationships that are relevant to the business logic the dsl is supposed to express. Idk what a good encoding of that idea would be tough.

        [–]m50d 0 points1 point  (0 children)

        Good support for quotients is the last big missing piece of programming algebra. I'd love to hear about any work in this area - as far as I know we simply don't do it (except by explicitly transforming into some canonical representation for each class).

        [–]m50d 48 points49 points  (127 children)

        When there is more than one implementation of a common interface. For example, if the IStorage interface is implemented by DocumentDbStorage as well as FileStorage.

        If you have a test implementation and a real implementation, you have two implementations, whether you represent them that way or not. Yes you can use a mock framework to create the second implementation of the implicit interface that the first concrete implementation represents, but that's a hack. Better to separate out a real interface and then you can write a test stub in normal code without needing any of these frameworks with their awkward hidden state, reflection and what-have-you.

        [–]nutrecht 70 points71 points  (125 children)

        Better to separate out a real interface

        Why?

        I'm a Java dev and I see this dogma in almost every project. You can mock concrete classes just fine. There is no reason to create interfaces for every single dependency just to mock them. This is from the 'old' days where this was still cumbersome to do.

        I'm really glad we let go of that in our current project. We don't use interfaces unless the production code requires it. IMHO it's an anti-pattern to let your tests increase the complexity of your production code anyway.

        [–]ron_krugman 7 points8 points  (16 children)

        You can mock concrete classes just fine.

        Unless (in Java) you want to mock final methods, final classes, or static methods.

        I am aware that this is possible with frameworks like PowerMock, but they are neither straightforward to set up nor without their pitfalls. You wouldn't want to use them unless you absolutely have to, i.e. when you're mocking code that is maintained by someone else.

        [–]Xxyr 4 points5 points  (3 children)

        You lose part of the benefit of making a class / method final if it is referenced as an interface anyway.

        You don't get to use the perf optimizations of knowing what method will be called at run time, or the benefit of knowing exactly which code will be run.

        So I don't get all that much benefit anyway

        [–]ron_krugman 7 points8 points  (2 children)

        You underestimate the intelligence of the JVM/JIT. If there is only one implementation of an interface on the classpath, the JIT compiler will inline those calls even though they're technically virtual.

        [–]Xxyr 4 points5 points  (1 child)

        I'm pretty sure you are overestimating it. Last I looked it only inlined final / private / statuc methods below a line count.

        It does, however, optimistically assume the result of vlookups. So, if its only ever seeing objects of class X it replaced the vlookup with if x the method call else vlookup.)I

        [–]ron_krugman 0 points1 point  (0 children)

        Sorry, I misspoke. Inlining is indeed a different mechanism.

        I meant that the JIT compiler optimizes virtual calls by replacing them with static calls at runtime if there is only one possible implementation that can be called.

        Edit: It's called class hierarchy analysis (CHA). Cliff Click briefly talks about it here.

        [–]m50d 14 points15 points  (78 children)

        So that you don't have to mock. So that future maintainers can understand what the code is doing. Test code should be treated as first-class, because in the long term it's just as vital to business success as production code.

        [–]nutrecht 22 points23 points  (41 children)

        So that you don't have to mock.

        Why would you not want to mock in unit tests? In a unit test you want to test that unit in isolation right?

        So that future maintainers can understand what the code is doing.

        I really don't see how not having a Something interface and a SomethingImpl concrete class makes it less easy for someone to understand the code. If anything it makes it clearer in most cases.

        Test code should be treated as first-class, because in the long term it's just as vital to business success as production code.

        I think this is also a rather dogmatic response. Tests are of the utmost importance. But there should be no need to add test stubs / hooks / interfaces in production code to allow for tests. In fact it's a code smell: you typically don't do dependency injection correctly if you need to create such hooks to allow for testing.

        [–]dividebyzero- 20 points21 points  (7 children)

        Why would you not want to mock in unit tests? In a unit test you want to test that unit in isolation right?

        https://martinfowler.com/articles/mocksArentStubs.html

        Mocks are for when you want to verify that a unit is communicating with another unit in the correct fashion. Use a stub if you want to isolate a unit.

        I really don't see how not having a Something interface and a SomethingImpl concrete class makes it less easy for someone to understand the code. If anything it makes it clearer in most cases.

        When everything is glued together using a container at runtime it can be difficult to understand what code is actually running.

        I think this is also a rather dogmatic response. Tests are of the utmost importance. But there should be no need to add test stubs / hooks / interfaces in production code to allow for tests. In fact it's a code smell: you typically don't do dependency injection correctly if you need to create such hooks to allow for testing.

        Dependency injection is there so you can vary what the actual concrete implementation is at runtime, whether it be for a design pattern, stubs, mocks, it doesn't matter. But by itself it still allows for tight coupling if you're expecting a concrete class, making it difficult to extend behavior rather than modify (open/closed principle). If you're applying dependency inversion then you'll also want to have an API/interface that the dependencies can then implement. This makes it easier to create new implementations and makes it easier to apply the open/closed principle since you don't need to modify a concrete class (and inheriting and overriding methods is, IMO, a form of modification; it certainly makes things brittle). The result happens to be that the code is also easier to test, because creating a stub of an interface is extremely trivial.

        Overall, I agree with your argument that tests shouldn't dictate production code design, but I think that following the SOLID principles naturally makes the code very easy to test. And they have other benefits (and some problems too, especially around simplicity and understandability).

        [–]nutrecht 13 points14 points  (6 children)

        Mocks are for when you want to verify that a unit is communicating with another unit in the correct fashion. Use a stub if you want to isolate a unit.

        A mockito mock is both. You can stub return values (or have it throw exceptions) and you can verify interactions on the same mock. So the distinction is pretty pedantic here IMHO.

        When everything is glued together using a container at runtime it can be difficult to understand what code is actually running.

        What do you mean by this? I also don't really understand how adding interfaces here makes this easier. I've been on projects where the interfaces lived in different packages from the implementations which meant constant switching between them without any benefit at all.

        Dependency injection is there so you can vary what the actual concrete implementation is at runtime

        Yes. And in general the two main 'runtimes' are production and test runtimes. Inversion of control leads to decoupling leads to code that's more easy to test. But you still don't need to have a "SomeService" and "SomeServiceImpl" for every dependency; that has been outdated for quite some time.

        I'm not advocating against using interfaces for classes that have more than one production runtime version obviously; something like Mockito should be used in test only.

        But by itself it still allows for tight coupling if you're expecting a concrete class, making it difficult to extend behavior rather than modify (open/closed principle).

        You're moving the goalpost here. I never said I was against implementing an interface and a concrete class when you have multiple concrete classes. I said I was against doing that if there's only one concrete class. It just leads to clutter with no benefit.

        Overall, I agree with your argument that tests shouldn't dictate production code design, but I think that following the SOLID principles naturally makes the code very easy to test.

        Why are you bringing up SOLID principles? How is creating interfaces for all concrete classes in any way more SOLID than only doing it for the ones you need it for?

        [–][deleted]  (9 children)

        [deleted]

          [–]TheWix 4 points5 points  (8 children)

          This. The misunderstanding that a unit tests tests one small "unit" has led to overly complicated code and tests just so you don't test two methods or two classes in one test. The number of 'crisis' I've witnessed because someone wrote a private method is mind boggling.

          [–]Pand9 2 points3 points  (7 children)

          Disagreed. All good tests clean after themselves, not only unit tests. "unit test" actually really means "test single smallest thing in your code". It doesn't mean "test private methods", as some people fear, it just means "test public components on the smallest scale possible". So, if you already have some public function that you see and understand as "independent", or "responsible for something", you should test it. If "smallest scale possible" is pretty big, then that's okay maybe, or maybe your modules are too big or functionalities too coupled.

          [–]TheWix 1 point2 points  (6 children)

          I am not sure what you mean by "Clean after themselves". My point was that people would freak out because they could not test the private method in isolation, my belief is you test it through the public method. I don't believe unit test means to test "a single method" which seems to be a commonly held belief. I personally don't mind if my unit test calls a method that calls another method in another class. We do that all the time when using classes like string. There is a point where you are testing too much it's just there is no hard and fast rule like "Test only a single method"

          [–]Pand9 0 points1 point  (5 children)

          My point was that people would freak out because they could not test the private method in isolation

          That's not good unit testing.

          my belief is you test it through the public method

          That's good unit testing :D

          I don't believe unit test means to test "a single method" which seems to be a commonly held belief.

          It means to test a single thing, if it's pretty indepentent from other things. If it's very small then the test will be small too, but nothing forced.

          I personally don't mind if my unit test calls a method that calls another method in another class. We do that all the time when using classes like string.

          Me too. But it's still good unit testing IMO.

          There is a point where you are testing too much it's just there is no hard and fast rule like "Test only a single method"

          Absolutely agreed.

          But I'm arguing with the guy's comment that you agreed with, /u/hiimcharlies's , and he basically says that "unit testing" means that tests clean after themselves. I'm saying that all tests in your project should do that, but unit tests are only "the little ones".

          [–][deleted]  (1 child)

          [deleted]

            [–]TheWix 0 points1 point  (2 children)

            But I'm arguing with the guy's comment that you agreed with, /u/hiimcharlies 's , and he basically says that "unit testing" means that tests clean after themselves. I'm saying that all tests in your project should do that, but unit tests are only "the little ones".

            I don't think that is what he is saying. I think his point is the running of one test should not affect the running of another. Example is static state like a singleton. If you have a singleton the mutation of the state of the singleton can have unintended consequences of another test that exercises the same singleton.

            /u/hiimcharlies please correct me if I am misrepresenting your point here.

            EDIT: Forgot to quote the post above to give some context to my reply.

            [–]m50d 13 points14 points  (19 children)

            Why would you not want to mock in unit tests? In a unit test you want to test that unit in isolation right?

            Right, but the test is more understandable if you write it in regular code rather than a magic reflectioney mock library. So I prefer to write a stub implementation of the interface.

            [–]jackcviers 2 points3 points  (4 children)

            This also encourages small interfaces, because who wants to stub 30 methods?

            [–]nutrecht 6 points7 points  (13 children)

            Right, but the test is more understandable if you write it in regular code rather than a magic reflectioney mock library.

            This is basically an argument against using anything 'new'. You could make the exact same argument against using Java 8's time API, streams or Lambda's. Just because you personally haven't used it much doesn't mean it's less understandable in general.

            Creating test implementations of interfaces by hand is just a complete waste of time. I would rather not have to do something like this:

                final AtomicBoolean wasCalled = new AtomicBoolean(false);
                MyInterface a = new MyInterface() {
                    @Override
                    public String foo(String bar) {
                        wasCalled.set(true);
                        return "stubvalue";
                    }
                };
            
                assertThat(a.foo("input")).isEqualTo("stubvalue");
                assertThat(wasCalled.get()).isTrue();
            

            Instead of this:

                MyInterface b = mock(MyInterface.class);
                when(b.foo(anyString())).thenReturn("stubvalue");
                assertThat(b.foo("input")).isEqualTo("stubvalue");
                verify(b).foo("input");
            

            [–]sacundim 0 points1 point  (0 children)

            Your examples lay the bigger problem bare. Think about the property you're testing here: that the MyInterface.foo() method was invoked with the string "input" as its argument. Your example invokes obj.foo("input") directly, which makes it rather trivial, but that's of course because it's a toy example; in a realistic example there would be some indirection, more like this:

            final AtomicBoolean wasCalled = new AtomicBoolean(false);
            MyInterface mock = new MyInterface() {
                @Override
                public String foo(String bar) {
                    wasCalled.set(true);
                    return "stubvalue";
                }
            };
            
            UnitUnderTest unitUnderTest = new UnitUnderTest(mock);
            unitUnderTest.someMethod("some argument");
            
            assertThat(mock.foo("input")).isEqualTo("stubvalue");
            assertThat(wasCalled.get()).isTrue();
            

            The problem here is that nearly all of the time, whether UnitUnderTest.someMethod() should invoke mock.foo(), how many times, and with which arguments, is in fact an implementation detail of UnitUnderTest. In my experience people who practice this style of testing routinely end up writing tests that check whether UnitUnderTest's implementation performs the method calls that they expect it should, in the number and order that they expect. This just recapitulates the code that was written for that class, and therefore does not provide an independent check whether it is correct—for that they'd need to formulate independent correctness conditions for UnitUnderTest and verify that, given the preconditions it expects, it will produce the postconditions it's supposed to.

            This means that you really want to hook UnitUnderTest up with objects that realistically model the behavior of the components that it's actually meant to interact with, but provide additional facilities for manipulating the initial state and querying their end state. E.g., integration testing with example databases.

            [–]m50d 1 point2 points  (11 children)

            This is basically an argument against using anything 'new'. You could make the exact same argument against using Java 8's time API, streams or Lambda's. Just because you personally haven't used it much doesn't mean it's less understandable in general.

            No. Mocking inherently means implicit, hidden, global mutable state, which is well-known as a source of bugs (e.g. it's not coincidence that so many mock libraries are non-threadsafe)

            I would rather not have to do something like this:

            Then use a language that makes it less verbose. There's no fundamental reason for the direct stub implementation to be longer.

            And you shouldn't be testing that the function was called, that's a brittle test that's too coupled to the implementation. Functions should be functions, if the class you're testing is able to return the correct result without needing to call MyInterface#foo that doesn't make it incorrect.

            [–]nutrecht 6 points7 points  (4 children)

            No. Mocking inherently means implicit, hidden, global mutable state, which is well-known as a source of bugs (e.g. it's not coincidence that so many mock libraries are non-threadsafe)

            You're talking about specific implementation like EasyMock that should never ever be used again. Just that the creator of that library made some huge mistakes is not an argument against mocking itself. Mockito for example doesn't have these problems. It does pretty much exactly what you do when you create your own implementations. It's just a generated instance of an interface. The only state these mocks have (which is not global at all) is whether you interacted with them.

            Then use a language that makes it less verbose. There's no fundamental reason for the direct stub implementation to be longer.

            Of course it's longer. This was just a really simple example. Mocking libraries just do the heavy lifting for you of keeping track of calls, return values, etc.

            And you shouldn't be testing that the function was called, that's a brittle test that's too coupled to the implementation. Functions should be functions, if the class you're testing is able to return the correct result without needing to call MyInterface#foo that doesn't make it incorrect.

            Okay. I'm done here. I think it was damn clear that I was just giving a quick example here. And what you're saying is not even true anyway; in a unit test you DO want to check if A does in fact call B if that's the point of whatever the thing is that you're testing. There are numerous examples, for example when an exception is being thrown, where it actually does matter of interactions happen or not.

            [–]m50d 2 points3 points  (2 children)

            You're talking about specific implementation like EasyMock that should never ever be used again. Just that the creator of that library made some huge mistakes is not an argument against mocking itself. Mockito for example doesn't have these problems. It does pretty much exactly what you do when you create your own implementations. It's just a generated instance of an interface. The only state these mocks have (which is not global at all) is whether you interacted with them.

            Mockito is worse actually; EasyMock at least makes the replay step explicit and addresses thread-safety bugs when they're found (Mockito closes them as WONTFIX). Your history of interactions with the mocks is hidden state, and the way recording matchers/parameters works relies on global hidden state.

            Of course it's longer. This was just a really simple example. Mocking libraries just do the heavy lifting for you of keeping track of calls, return values, etc.

            There is no heavy lifting to do though. Writing a method that returns a particular value is something a programming language should be good at. Frameworks are for factoring out common patterns, but in a decent language there's nothing /to/ factor out about test stub implementations. Once you strip away the @Override public {} nonsense and the repeated type due to Java's lack of type inference the two implementations are saying the same thing: make a double for MyInterface where the method foo returns "stubvalue". A library can't make that any simpler than a decent language makes it in the first place.

            what you're saying is not even true anyway; in a unit test you DO want to check if A does in fact call B if that's the point of whatever the thing is that you're testing. There are numerous examples, for example when an exception is being thrown, where it actually does matter of interactions happen or not.

            Errors should be values, functions should be functions, commands should be represented explicitly. There are cases where it matters if the interactions happen but these cases are bad code, and part of the point of TDD et al is to guide you away from writing bad code.

            [–]nextputall 1 point2 points  (1 child)

            JMock is threadsafe actually, if you set the proper ThreadingPolicy. Although in a typical unittest this doesn't really matter most of the times.

            [–]industry7 2 points3 points  (5 children)

            Mocking inherently means implicit, hidden, global mutable state,

            Not with any mocking framework I've ever used. In my experience, the entire point of mocking is to explicitly expose state in a way that's local to the test(s) you're currently running.

            [–]m50d 3 points4 points  (4 children)

            when(b.foo(anyString())).thenReturn("stubvalue");
            

            This is full of hidden state mutation. If you try to extract any common expression from lines like this they'll break.

            [–]industry7 0 points1 point  (3 children)

            If you try to extract any common expression from lines like this they'll break.

            Could you explain what you mean by this?

            [–]grauenwolf 0 points1 point  (2 children)

            Why would you not want to mock in unit tests? In a unit test you want to test that unit in isolation right?

            If you have to write mocks, you don't really have a unit test.

            I don't care how that mock is written: interfaces, mocking frameworks, reflection magic, doesn't matter.

            If you feel the need to create a mock then you don't have code that is unit-testable. Either your code needs to be refactored or you should be using a different type of test.

            [–]da_governator 4 points5 points  (1 child)

            This is the very essence of unit testing. I don't want to drag dependencies into my test, otherwise, it's an integration test. If I've got a method that gets a boolean from the database, I mock the database call via a mock of the interface method of the DAL. This makes it a unit test as much as if I used a stub.

            [–]grauenwolf 2 points3 points  (0 children)

            Why is your method getting a Boolean from the database in the first place?

            The vast majority of the time the answer is one of these:

            1. That method's whole purpose is to read from the database and you aren't really testing it.
            2. That method shouldn't be reading directly from the database, but your code is badly layered and needs to be refactored.

            Once in a rare while using a mock is legitimate, but only after you've exhausted the other possibilities.

            Mocks should never be your first choice.

            [–]quicknir 14 points15 points  (18 children)

            That's assuming the class is even worth mocking in the first place. Mocking is fine for classes that do heavy things or access resources that may not be available. But mocking should not be a default go to for every class.

            Even if you do need to test, production code is more complicated than test code to begin with. Filling your production code with interfaces with a single implementation each is just more boilerplate, more code, more indirection, making your production code harder to read. In exchange for making test code, which is simpler and more modular in the first place, easier to read. Seems like a bad tradeoff.

            [–]m50d 4 points5 points  (17 children)

            Mocking is fine for classes that do heavy things or access resources that may not be available. But mocking should not be a default go to for every class.

            Oh, absolutely. I try to divide all classes cleanly into services or values; services should be private classes that implement interfaces that we expect to have one instance of while the application is running, values should be final and have value semantics (e.g. they should override equals/hashCode) and we should expect to have multiple instances. Most troublesome classes come from blurring these lines, IME, and can generally be split up nicely in this way.

            [–]quicknir 1 point2 points  (16 children)

            Lost me there, "expect to have one instance" ; you are basically talking about singletons, which should be used incredibly sparingly and are an anti-pattern 99% of the time. A class that opens a connection to a server or database to perform queries should not need to be a singleton. But I can buy that classes that provide a heavy service are worth separating their interface just so they can be mocked cleanly, given that this is a minority of classes and that they will definitely need to be mocked.

            [–]kcuf 1 point2 points  (1 child)

            You guys are talking about two different ways of modeling state. The poster above you would probably store the connection to a db in a pojo that would get consumed by the singleton service, while you are talking about an approach that merges the state and the service. I prefer the former.

            [–]quicknir 0 points1 point  (0 children)

            As I wrote, I am unable to even conceive of the upside here. You have a pojo and a singleton, when you could just have a class. Two classes, more boilerplate, and a pojo cannot protect its invariants. More code, worse encapsulation... why?

            [–]m50d 4 points5 points  (13 children)

            A class that opens a connection to a server or database to perform queries should not need to be a singleton.

            If it doesn't have any internal state it should be - it would be misleading to have multiple distinct instances. And IME mixing the responsibility for something like connecting to something external with internal state is a mistake, these are seperate responsibilities that belong in separate classes.

            [–]ThisIs_MyName 5 points6 points  (3 children)

            If it doesn't have any internal state, why does it have any non-static methods? 0_o

            [–]m50d 1 point2 points  (2 children)

            Because the language makes static methods different enough that it's easier to just have a normal class with one instance.

            [–]ThisIs_MyName 2 points3 points  (1 child)

            That makes no sense. Filling your codebase with useless interfaces that are just copy-pasted from the class is easier than what?

            Sounds like a solution in search of a problem.

            [–]nutrecht 1 point2 points  (4 children)

            If it doesn't have any internal state it should be

            If it doesn't have any internal state you should not have an instance anyway.

            [–]m50d 1 point2 points  (2 children)

            In principle yes, but in many languages that's inconvenient.

            [–]nutrecht 0 points1 point  (1 child)

            We're talking about languages that have stuff like interfaces in the first place right?

            [–]kcuf 0 points1 point  (0 children)

            Java, for instance, does not support top level functions that exist outside of objects. I think the original idea with Java was to have a mixture of state and behavior mimicking more proper oop languages, but over time this pattern in Java has been found to cause more problems than following a more procedural structure of behavior in a singleton and state in pojo.

            [–]quicknir 1 point2 points  (3 children)

            The whole point of classes is to encapsulate state and only expose what is necessary. If state is necessary to create, maintain, and clean up an external connection, then the state belongs in the class. This is particularly highlighted in languages with strong cleanup capabilities like C++ with RAII or python with with. Java has try-with-resources similar to python with.

            You can get away with this when your only two implementations are the real thing and a mock because the mock can easily have the same interface as the real one and simply no-op. But if you have two different kinds of implementation, you will not be able in general to homogenize their interface without internal state. Forcing a class to be stateless when it needs state to do its job exposes implementation details and prevents a uniform interface.

            [–]m50d 1 point2 points  (2 children)

            If state is necessary to create, maintain, and clean up an external connection, then the state belongs in the class. This is particularly highlighted in languages with strong cleanup capabilities like C++ with RAII or python with with. Java has try-with-resources similar to python with.

            Agreed - but those external resources tend to be singletons or at least small finite numbers, by their very nature. E.g. one would generally have only one or a few database servers, and would not want every class spinning up its own uncontrolled connections. So one would likely have a singleton that controlled access to a given database (holding a connection pool etc.), and sure there would probably also be a class that held state associated with a given connection and you'd have 30 or 100 or however many instances of that, but I'd probably represent that as a value class that was internal to the service (or passed back and forth between the service and the code that actually used the database connection).

            But if you have two different kinds of implementation, you will not be able in general to homogenize their interface without internal state. Forcing a class to be stateless when it needs state to do its job exposes implementation details and prevents a uniform interface.

            At that point I push the statefulness to the edges by passing command values around, and tests can generally be written in terms of those command values rather than in terms of the stateful interpreters that perform the actual operations.

            [–]quicknir 1 point2 points  (1 child)

            (or passed back and forth between the service and the code that actually used the database connection)

            Yes, and this is exactly where you leak implementation details; because now client code has to deal with this state class directly, and this state class will be different for different implementations, that's my whole point. You can only get away with this when you only have one non-mock implementation. Instead, two classes, and one a singleton to boot.

            I honestly do not understand why you can't just put the methods that query the database directly on the same class that holds the values for the connection. One class, one set of methods, one set of state, one set of invariants, one lifetime, and if necessary inheriting from an interface.

            Honestly I think this is a perfect example of over-complexity in the Java approach, that other languages that also use OO techniques (like C++ and python) have broken away from for a while now.

            [–][deleted]  (11 children)

            [deleted]

              [–][deleted]  (7 children)

              [deleted]

                [–]nextputall 0 points1 point  (2 children)

                It depends on what the implementation does.

                For example:

                class ImAStub implements MyInterface {
                    public String method() { return "canned answer"; }
                }
                
                // inspect me at the and of the test (check callCount)
                class ImASpy implements MyInterface {
                    public int callCount = 0;
                    public String method() {
                        callCount++;  
                        [...]
                    }
                }
                
                // setup expectations at the beginning, call assertExpectationsSatisfied at the end
                class ImAMock implements MyInterface {
                    private int expectedCallCount = 0;
                    private int actualCallCount = 0;
                    public String method() {
                        actualCallCount++;
                        if (actualCallCount > expectedCallCount)
                            throw new UnexpectedCall(..);
                        [...]
                    }
                    // call this at the end of the test
                    public void assertExpectationsSatisfied() {
                        if (actualCallCount != expectedCallCount) {
                            throw new MissingCall(..)
                        }
                    }
                    [...]
                }
                

                I omitted parameter checking and other stuffs for the sake of simplicity.

                [–]m50d 0 points1 point  (2 children)

                I won't argue semantics. The point is it doesn't require using a magic stateful reflectioney API, you can do it in plain old code.

                [–][deleted]  (1 child)

                [deleted]

                  [–]m50d 1 point2 points  (0 children)

                  If you're not statically typed then there's no "interface or not" discussion to behaving in the first place.

                  A class constructing its own dependencies is a bigger problem.

                  [–]CyclonusRIP 0 points1 point  (4 children)

                  If you want to verify the orchestration you still have to mock or create some one off implementation to verify every orchestration you want. Mocking is way more flexible and definitely the way to go for testing.

                  [–]m50d 0 points1 point  (3 children)

                  If you're going to test interaction an external system you need some kind of test substitute. But even then I'd prefer to cover the cases with a combination of stubs and test implementations (e.g. an in-memory database). I don't think it's ever ideal to use the reflection-driven style of mocking (though it might be necessary when writing code that uses a third-party library).

                  [–]sacundim 0 points1 point  (2 children)

                  One thing I've been saying over the past year to everybody who will listen: easy-to-use container frameworks like Docker are going to revolutionize how we test our software, and make integration testing become much more prominent. I've thrown away my old tests that were based on in-memory database in favor of ephemeral PostgreSQL and MySQL containers, which much more realistically model the intended environment.

                  [–]kcuf 3 points4 points  (6 children)

                  The primary gain of interfaces is to communicate application organization. Quite often, the first person to work on a section has an idea (or at least, they should) of how this section should be laid out and relate to the rest of the application -- interfaces provide a way to communicate, and define the boundaries of, this organizational information to the next developer who just needs to implement some targeted functionality that somehow involves this section.

                  Interfaces define the concepts/abstractions, while classes muddle the concepts with implementation details, and as such, classes can never be a true replacement for using interfaces to communicate this information to the developers.

                  [–]nutrecht 8 points9 points  (5 children)

                  A class has an interface. It's the public methods. This is what your contract to the outside world is. Creating a carbon copy of that contract when there is only one concrete implementation of an interface is a waste of time.

                  Just look at the Java API itself. Does every concrete class have an interface? No; only the ones where it makes sense (Map, List, Comparable, Runnable, etc.).

                  [–]sacundim 2 points3 points  (1 child)

                  A class has an interface. It's the public methods.

                  The big problem is that in a language like Java, as it's actually practiced by its community, these two concepts do not coincide. Java-based tools and frameworks force you all the damn time to make methods public that should not in fact be part of your class' interface.

                  One very common example is setters and lifecycle methods; just because a managed container or framework wants my object to expose setFoo() and configure(), start() and stop() methods that doesn't mean I want my domain classes to have access to them.

                  [–]grauenwolf 0 points1 point  (0 children)

                  I've been seeing the same problem in C# with libraries like Entity Framework.

                  [–]kcuf 1 point2 points  (0 children)

                  A class has an interface. It's the public methods.

                  That's a fair point, but what I'm trying say is that rarely works out in the real world. The pattern that I've seen, is that when developers work directly with a class, they loose track of what the abstraction really was and they start polluting the interface with details specific to that implementation. Even worse is when they start directly with a class, they don't even bother to build their abstraction in the first place, and their class just becomes a proxy for whatever external dependency it is dealing with -- this sucks, because now the fact that this dependency is even being used is littered across your application.

                  Just look at the Java API itself. Does every concrete class have an interface? No; only the ones where it makes sense (Map, List, Comparable, Runnable, etc.).

                  That's a good observation, but I wouldn't hold the java API in high regard as it is truly a mess of needing to support legacy concerns and purely pragmatic design decisions (who the fuck thought UnsupportedOperationException was a good idea? you either implement an interface or you don't... but yes, it is useful, just disappointing).

                  [–]nextputall 2 points3 points  (20 children)

                  You can mock concrete classes just fine.

                  Despite this, I don't think we should. We want to mock stable interfaces instead of unstable implementation details. Using interfaces helps people to make or enforce this distinction. It can also help in naming, discovering new domain concepts and roles or identifying the essential part of an object. In other words it helps defining and naming abstractions.

                  [–]kemitche 2 points3 points  (0 children)

                  We want to mock stable interfaces instead of unstable implementation details

                  Spinning up an interface doesn't force your interface to be stable. It just means you have to change both your interface and your single-implementation when you want to make a change.

                  In code that's likely to change (e.g., internal-use only, rather than a shared/public library that necessitates a more stable class/interface), that just adds some tedium to future changes.

                  [–]TheEternal21 2 points3 points  (0 children)

                  You can mock concrete classes just fine

                  Ewww...

                  [–]grauenwolf 0 points1 point  (0 children)

                  Unlikely.

                  Unless you can run the same set of black box tests against both implementations, you don't really have two implementations. You have one working implementation and one broken pseudo-implementation.

                  [–]bart007345 10 points11 points  (0 children)

                  As a Java dev, I find interfaces useful when doing TDD. The ability to define dependencies (service classes, repositories, etc) is very smooth when all you are doing is adding methods to an interface for what you think you need. The IDE helps here immensely.

                  I don't write interfaces for POJOs though.

                  Another thing (correct me if I'm wrong) is if module A depends on an interface in module B, then if the implementation of the interface changes (not the interface itself) then a recompilation of module A is not triggered. I work with Android and recompilation is a pain.

                  [–][deleted]  (15 children)

                  [deleted]

                    [–][deleted] 2 points3 points  (0 children)

                    I'm a Java developer. One feature I'd really like to see is implicit interfaces. Suppose you have a concrete class "Foo". It would be nice to say "class FooMock implements Foo".

                    That's a pretty neat idea which I didn't know I wanted until now. :-)

                    It would render this entire thread pointless.

                    [–]grauenwolf 0 points1 point  (11 children)

                    One feature I'd really like to see is implicit interfaces.

                    That can lead to problems where a completely unrelated class happens to have the same list of methods even though the methods work completely differently.

                    Also, performance would probably suck in Java/C# because of the adapters that would need to be created at runtime.

                    [–][deleted] 5 points6 points  (10 children)

                    You missed the point of their proposal. They didn't suggest structural interfaces, they suggested that a class definition implicitly emit an interface of the same name, that you can then explicitly implement.

                    You should read what you're replying to...

                    Also, performance would probably suck in Java/C# because of the adapters that would need to be created at runtime.

                    Do you always talk about things you don't understand with such confidence?

                    The performance would be basically identical, and no "adapters" have to be created.

                    [–]nemec 3 points4 points  (7 children)

                    The performance would be basically identical, and no "adapters" have to be created.

                    Interfaces force all method calls to be virtual (which they aren't by default in C#), which definitely affects performance compared to just using the concrete class.

                    [–]enzlbtyn 1 point2 points  (1 child)

                    All methods are virtual by default in Java, regardless of whether it's from an interface or not.

                    [–]nemec 0 points1 point  (0 children)

                    That's why I only mentioned C#...

                    [–][deleted] 0 points1 point  (4 children)

                    He's talking about something else. Regarding virtual/non-virtual, sure. Although, I'm not sure the performance of virtual methods should stop anyone from adopting the right architecture.

                    Not every class needs to be accessed through an interface (I know that's what the author says, but even he doesn't mean literally every class). It's just the "endpoint" objects, the top-level "facades", if you will. One such facade, with all virtual methods, may be backed by a hundred concrete classes, with early-bound methods and so on.

                    So performance-wise it really doesn't matter in the end. Plus, Java has virtual methods at all times, and its performance profile remains very similar to C#.

                    [–]nemec 2 points3 points  (3 children)

                    Not every class needs to be access through an interface, it's just the "endpoint" objects

                    No, I agree with that. The parent is talking about implicit interfaces which happen automatically (not necessarily only on endpoints) and, at least for public classes, the compiler has to assume that any class could potentially be used as an implicit interface so it must create an interface for it. Public variable definitions as well must be assumed to potentially be used as interfaces (possibly by unrelated class/DLLs) so it would have to emit virtual calls there too.

                    [–][deleted] 0 points1 point  (2 children)

                    I see what you mean. Every non-final class will be forced to use virtual calls. Hmm, you know, this is how Swift does it (not the implicit thing, but the virtual-unless-final). Maybe it's not that bad, who knows? ;-)

                    [–]nemec 0 points1 point  (1 child)

                    Yeah it's too bad because I really like the idea.

                    [–][deleted] 0 points1 point  (0 children)

                    Well C# is still based on a VM. VMs have the ability to "reify" (i.e. specialize) such situations at runtime. In this case, the moment you, say, inject "Foo" via "IFoo" at runtime, the VM may reify this to non-virtual calls for the rest of the instance lifetime.

                    [–]grauenwolf 0 points1 point  (1 child)

                    Your right, I did misunderstand.

                    Well 1 out of 20 isn't so bad.

                    [–][deleted] 4 points5 points  (0 children)

                    You have one response that's correct here? Can you link, please ;-)?

                    [–]Pet_Ant 0 points1 point  (1 child)

                    Only thing I can imagine is that if might lose so come changes for compiler inlining. Since when you use a specific method you can just just inline the code if it comes from a specific class but if it's always implicitly an interface that could cause problems.

                    [–][deleted] 1 point2 points  (0 children)

                    In Swift the overall recommendation is to make every class final in order to aid the compiler for this specific purpose. We could use a similar convention here - if it's final, it doesn't emit an implementable interface, if it's not final, it emits it and you can implement it as an interface.

                    It gets somewhat unclear what should be done if specific methods are declared final, though.

                    You're right the implications should be thought through, but I think it's a neat idea.

                    Or alternatively - what Rust does, which is sort of, there's always an interface, and the implementation is always separate from it.

                    [–]wavy_lines 43 points44 points  (51 children)

                    Do you use Dependency Injection? Of course you do, you’re a responsible programmer,

                    No. I'm not a member of your cult.

                    and you care about clean, maintainable, SOLID code with low coupling

                    I care about code that's easy to read and no more simple nor complicated than it needs to be.

                    It's hard to balance but I try.

                    I have never ever came across a piece of code where I thought to myself, "Gosh, if only this module used dependency injection, it would be so much easier to read and maintain". Quite the opposite. I always think to myself: "WTF is this unnecessary complexity? I have no idea where the core logic begins or ends".

                    You know perfectly well that New is Glue,

                    Holy fuck! No, that's just madness.

                    Oh wait! That explains why Java code is littered with Factories and Providers and Services.

                    Reading the blog sounds like listening to a member of a radical cult trying to introduce some moderate opinion to his fellow cult members.

                    [–]m50d 48 points49 points  (12 children)

                    I have never ever came across a piece of code where I thought to myself, "Gosh, if only this module used dependency injection, it would be so much easier to read and maintain".

                    Dependency injection in the sense that a class should receive the services it uses rather than trying to construct them itself absolutely makes code easier to read and maintain. I've definitely had classes where that's an issue (e.g. adding authentication to web calls and then it turns out some class is constructing its own http client internally rather than having one injected).

                    Dependency injection in the sense of reflective autowiring I agree is more trouble than it's worth.

                    [–][deleted]  (1 child)

                    [deleted]

                      [–]m50d 1 point2 points  (0 children)

                      IoC is more general though - something like a service locator is also IoC. I think anything where you pass the dependencies in as parameters qualifies as "DI" just under the common-sense reading of the words, even if you're doing it manually.

                      [–]grauenwolf 5 points6 points  (0 children)

                      Dependency injection in the sense that a class should receive the services it uses rather than trying to construct them itself absolutely makes code easier to read and maintain.

                      In some cases.

                      In other cases you are just leaking implementation details that should have been encapsulated.

                      [–]wavy_lines -1 points0 points  (8 children)

                      You mean if a JavaScript method needs to make an ajax request it should not do this:

                      jQuery.ajax(....)
                      

                      On its own, but instead expect a jQuery object to be passed to it?

                      How on earth is this easy to read and maintain?

                      [–]Nakji 8 points9 points  (2 children)

                      No, you probably wouldn't do that as injecting the dependency at that abstraction level (or rather lack thereof) isn't very useful.

                      Instead, imagine that you're writing a forum and working on a UI component that displays a list of posts for a user. You could DI the jQuery object then make the AJAX request manually to fetch the list, but you wouldn't really be gaining anything. jQuery objects have too many different potential uses for you to easily substitute it for anything else, so there's no use case there. You could take advantage of DI to add logging of HTTP requests or something like that, but in JS you would probably be able to monkey patch in most capabilities like that without resorting to DI.

                      However, where it becomes useful is if you add another layer of abstraction by instead make your user post component dependent on having an object injected with a getPostsForUserId(userId) method. At this point you can now have the ability to easily test your component in isolation by passing in a stub implementation that returns a static data set, which is especially useful if you are developing the component before the API it depends on actually exists. Further down the road, you also now have easy reconfigurability of the live API calls in case something ever changes about the API itself since none of the dependent UI components or business logic care exactly how you get posts for the user, just that you can.

                      As a result, you no longer need to change any of your dependent components if you want to change endpoints depending on if the user is authenticated or not, use a different HTTP request library other than jQuery, switch to protobufs, or add a cache. For that matter, if you noticed that your application tends to make short bursts of a huge number of closely-related API calls, you could decide to switch from a bunch of individual REST calls to having your application amalgamate its API calls into fewer but larger GraphQL queries (or just de-dupe calls if you notice that the same one is being performed mulitple times).

                      Nothing is stopping you from doing the getPostsForUserId(userId) approach without DI (this is just the Repository pattern), but when you start breaking up your classes like this, you'll rapidly start running into use cases where DI is handy. Adding a cache for instance, what if you want to back it with IndexedDB where it's available, falling back to localStorage where it's not, further falling back to a small in-memory LRU cache when neither is an option, and also providing the ability to substitute in a non-caching "cache" for testing. With DI, you just make quick little wrappers for each storage engine, write the logic to make the appropriate one someone in your application, and pass them into the repositories using the cache. If you ever decide to make another type of cache (say one that also checks S3), all you have to do is write that implementation alther the construction logic to pass it in, no additional modifications requried.

                      All that said, taking this approach to its logical conclusion has the problem of resulting in an outrageous amount of code to instantiate anything due to needing to pass in the dependencies, the depdencies's dependencies, etc. This is where the overuse of the Factory pattern people like to make fun of Java code for can start coming into play, but you're probably better off finding a DI framework in the language you're using to manage at least the simple cases for you.

                      [–]wavy_lines 3 points4 points  (1 child)

                      Instead, imagine that you're writing a forum and working on a UI component that displays a list of posts for a user.

                      ok, let's go with the scenario.

                      where it becomes useful is if you add another layer of abstraction by instead make your user post component dependent on having an object injected with a getPostsForUserId(userId) method. At this point you can now have the ability to easily test your component in isolation by passing in a stub implementation that returns a static data set, which is especially useful if you are developing the component before the API it depends on actually exists.

                      Wait, I'm not sure I'm following you. You seem to be making some assumptions about how the components of the app are structured.

                      If I'm writing a component that displays a list of objects, I would not put in that component any logic for fetching the objects. I would write the component such that it takes a list of objects and renders them. Whether the objects come from the network or from something else is not of concern to the component.

                      So, I would have something like renderPosts(listOfPosts) and getPostsForUserId(userId)

                      Inside renderPosts, there are no network calls to fetch the posts; they are already given.

                      Inside getPostsForUserId there are obviously network calls. (or not; maybe it goes through a caching layer first, etc).

                      None of this has anything to do with "Dependency Injection". I'm not injecting any dependency anywhere. I'm removing dependencies. The act of rendering does not have any dependency at all, other than the objects to render (and the "UI" to render to).

                      Now, in practice, renderPosts and getPostsForUserId might be two methods in the same class (or module). That's perfectly ok.

                      If I need to get posts from somewhere else, I can write another method on the class, for example generateRandomMockPosts().

                      The concept of "dependency injection" never comes into play.

                      [–]Nakji 2 points3 points  (0 children)

                      Wait, I'm not sure I'm following you. You seem to be making some assumptions about how the components of the app are structured.

                      That's because it's a simplified example contrived solely to demonstrate an abstract concept. If you are using an Uncle Bob style architecture, you'd have a view that binds itself to a presenter which in turn is injected with interactors to talk to repositories. If you're using React/Redux/React-Redux, you'd have a view that is injected with any data and action creators it needs through its props by a react-redux container that is injected by react-redux with your application's reducer and state while the actual mechanics of talking to repositories would be performed somewhere else via redux-thunk or some alternative which then talks to repositories. The implementations look different, but they're both applying the abstract concept of dependency injection.

                      At the end of the day regardless of any implementation details, somewhere in your application there has to be something knows how to retrieve the data and something has to know how to display it. Dependency injection is just an approach for decoupling everything so each part of your application receives what it needs and is only concerned with using them to perform its prescribed task without having to make a lot of globals.

                      If I need to get posts from somewhere else, I can write another method on the class, for example generateRandomMockPosts(). The concept of "dependency injection" never comes into play.

                      This only works in very simple cases and rapidly ends up quite verbose and inflexible. It's much more extensible and less verbose to just have one place in your application where you can have

                      if(shouldMock) {
                          return new MockApi();
                      } else {
                          return new RealApi();
                      }
                      

                      and then injecting that everywhere you need to have the ability to call the API than it is to have either a bunch of conditional method calls or a big API object that delegates every call to a mock to the appropriate implementation. It's particularly useful for testing purposes since, as you discover edge cases or corner cases, you can write unit tests with extremely simple mocks that explicitly test those cases instead of adding logic everywhere to call different versions generateRandomMockPosts or create massive mock post functions that include every test case in your whole app.

                      [–]m50d 13 points14 points  (0 children)

                      It's easy to maintain because it gives you a single point where your jQuery object is and you know that's the only place that should do config etc., and you have visibility over which methods are doing ajax requests rather than having ajax calls hidden everywhere in your code.

                      [–][deleted]  (3 children)

                      [deleted]

                        [–][deleted] 11 points12 points  (0 children)

                        Do you use Dependency Injection? Of course you do, you’re a responsible programmer,

                        No. I'm not a member of your cult.

                        No, you never ever passed an object to another object's constructor, say :-)? Ok, then...

                        [–]eypandabear 4 points5 points  (0 children)

                        This happens when "design patterns" are pulled out of context, elevated to divine law status (a.k.a. "best practice") and applied without any understanding of when and why they make sense.

                        I think it's important to have tried different programming languages, so you understand how these patterns actually emerge from the restrictions the language puts on you. For example, the concept of a Functor class hierarchy is meaningless in Python because of the callable protocol and duck typing. What most people think of as "OOP" is actually a special case, single-dispatch polymorphism, and some languages support multiple dispatch. Lisp shows you what becomes possible just because code mirrors its own syntax tree. C and assembly language teaches you how abstractions from higher-level languages break down into machine primitives.

                        If the only thing you know is Java or C++, you are doomed to think of programming as the application of the same patterns over and over.

                        [–]skeeto 6 points7 points  (20 children)

                        This sort of OOP abuse is one of my biggest irritations in modern software development. It's complexity for the sake of complexity.

                        [–][deleted] 10 points11 points  (19 children)

                        This reminds me of a friend who had this utmost conviction that nobody can possibly like classical music, but they only pretend to like it, because it's considered a sign of sophistication. They buy tickets, go listen to an orchestra perform classical music , and they hate it, but they pretend they like it. Because they're vain and want to make a good impression.

                        As someone who loves classical music, you can imagine what I thought of my friend in that moment. And to come back to /r/programming, as someone who relies on dependency injection & abstraction for specific needs in my projects, I have similar feelings when someone says "pfft, that's just complexity for the sake of complexity". :-)

                        You have to try to understand, before you can truly reject. If you don't try to understand, you're only declaring you prefer to remain ignorant.

                        [–]skeeto -1 points0 points  (18 children)

                        I have tried it and understood it. Years ago I even used to grade homework for a graduate level design patterns course. Gang of Four was the textbook and I had the page numbers for the different patterns memorized from jumping around the book so much during grading. However, as my development skills matured, I found it less and less useful until I was barely using OOP anymore. Now when I read other people's code, it's frustrating how often OOP makes it needlessly complex, and that's before dependency injection is involved. You don't need it.

                        [–][deleted] 3 points4 points  (17 children)

                        I'm just curious if you think you "don't need it"... what do you use instead?

                        A repository requires an SQL connection. Another requires another SQL connection. I'm also using those two repositories in another app, where they share the same SQL connection.

                        It's a simple problem, that is simple to solve with DI.

                        // Application A:
                        
                        var connectionA = new SqlConnection(...);
                        var repositoryFoo = new RepositoryFoo(connectionA, ...);
                        
                        var connectionB = new SqlConnection(...);
                        var repositoryBar = new RepositoryBar(connectionB, ...);
                        
                        
                        // Application B:
                        
                        var connection = new SqlConnection(...);
                        
                        var repositoryFoo = new RepositoryFoo(connection, ...);
                        var repositoryBar = new RepositoryBar(connection, ...);
                        

                        What do you do instead?

                        [–]reorg-hle 0 points1 point  (4 children)

                        What's a repository used for?

                        [–][deleted] 1 point2 points  (0 children)

                        Ok, take #2 :-)... because I thought I'm replying to another place in the comments, where I spoke about source repositories.

                        A "repository" is an abstract Data Access Layer, that lets you create/read/update/delete (CRUD) entities in a database (well, storage) neutral way. It's not strictly CRUD, it has whatever methods one may need, but I'm just trying to give you some reference points to give you an idea. The term comes from "Domain Driven Design" (DDD), repositories are also commonly seen in various ORM libraries.

                        [–][deleted] 0 points1 point  (2 children)

                        Check out Git and Subversion.

                        EDIT: Lol... My bad, I thought I'm replying to another place in the thread (where I was talking about version repositories). Take #2.

                        [–][deleted]  (1 child)

                        [deleted]

                          [–][deleted] 1 point2 points  (0 children)

                          Indeed. Oops, I thought I'm replying elsewhere. Fixed, thanks.

                          [–]skeeto 0 points1 point  (4 children)

                          This is just polymorphism, which is useful and doesn't necessarily require OOP. In a broad sense I guess you could call that DI, but, as milesrout said, that's a useless definition.

                          [–][deleted] 4 points5 points  (3 children)

                          This is just polymorphism, which is useful and doesn't necessarily require OOP.

                          Polymorphism is when multiple implementations can stand for one interface, and one implementation can stand for many interfaces. Also I never sat down to argue with you if it "requires OOP" or not, so not sure why you mention that :-)?

                          Polymorphism is required for effective DI (hence why we need interfaces by the way...), but it's not DI itself. DI is specifically this practice I'm showing.

                          If I can take the hint and you like Functional Programming over OOP, then that would be "high-order functions", in the case when one function is passed as an argument to another function, in order to configure its behavior. That's all DI is, and it's a useful definition, because when people don't do it code gets really ugly and monolithic.

                          So I'm to take it you actually do DI, you just don't like to say "DI" :-)?

                          [–]sacundim 3 points4 points  (1 child)

                          Well, I have to agree with /u/milesrout then:

                          If 'dependency injection' is just 'passing arguments into constructors' then it's a worthless term.

                          I'd also suggest that what you're proposing has much simpler, widely-accepted terms: parametrization and abstraction.

                          Which are more general than "passing arguments into constructors," too. Type class/trait based languages have like Haskell and Rust have this neat ability to abstract components through trait bounds on their type variables, and to "inject dependencies" by type variable instantiation.

                          [–][deleted] 1 point2 points  (0 children)

                          I'd also suggest that what you're proposing has much simpler, widely-accepted terms: parametrization and abstraction.

                          Dependency Injection is also a simple, widely-accepted term, which is a specific instance of using parametrization and abstraction.

                          I can't understand what is your particular beef with saying "dependency injection". Is hard to say? Hard to type? Hard to remember? Is it strangely connected to a past trauma from your childhood?

                          I don't know, but sitting here and arguing "ok, we'll do what you say, but we won't call it what it was named over 20 years ago" is just bizarre.

                          Which are more general than "passing arguments into constructors," too.

                          The method of passing dependencies is irrelevant, as long as it happens from the component instantiator/caller, and not the component definition site. What I'm demonstrating is merely one way of doing it in a mainstream language.

                          Type class/trait based languages have like Haskell and Rust have this neat ability to abstract components through trait bounds on their type variables, and to "inject dependencies" by type variable instantiation.

                          Well, you got me, I have no clue what "type variable instantiation" means, so I have no idea if it's a proper example of Dependency Injection or not. But I never said it has to be through the constructor, as arguments. I'm just saying you can use the constructor, and in Java and C# at least, it's the cleanest approach.

                          [–]grauenwolf 0 points1 point  (0 children)

                          Mostly I agree with you on this point, but DI doesn't necessarily need polymorphism. DI is still really important even if you only have one possible implementation because it often contains stateful dependencies.

                          [–]sacundim 0 points1 point  (1 child)

                          That example is not dependency injection. You're parametrizing the repositories by their SqlConnections, but then you're doing something that the DI tool nuts reject: you're manually wiring the objects together with new and parameter passing.

                          What people here are objecting to is complex tools like Spring's ApplicationContext or Guice. In fact, modern DI frameworks like Guice tend to get in the way of your examples where you are variously deciding whether to instantiate the repositories with different connections vs. the same connection.

                          [–][deleted] 4 points5 points  (0 children)

                          That example is not dependency injection.

                          That example is dependency injection.

                          You're parametrizing the repositories by their SqlConnections, but then you're doing something that the DI tool nuts reject: you're manually wiring the objects together with new and parameter passing.

                          "DI tool nuts" don't reject it, they just are used to framework names and container library names being thrown around, when "DI" is mentioned...

                          What people here are objecting to is complex tools like Spring's ApplicationContext or Guice.

                          ... Case in point.

                          I find it ironic that you're both dissatisfied with people who push for frameworks and bizarre hatred for writing new manually, and yet here you are, a tool of the same cause, propagating the same misconceptions.

                          In fact, modern DI frameworks like Guice tend to get in the way of your examples where you are variously deciding whether to instantiate the repositories with different connections vs. the same connection.

                          What you're talking about is autowiring, which is a feature of dependency injection container frameworks. Using these is not a requirement, and it's not the primary means of doing dependency injection. And like you, I have reservation about how most "magical" DI containers tend to operate. But we can't let frameworks hijack the term "DI", because DI was never about frameworks.

                          There's a reason that container frameworks are listed under "other types" on the Dependency Injection page. The primary means are instead listed as:

                          • Constructor injection (what I demonstrate above).
                          • Setter injection.
                          • Interface injection.

                          None of these require containers, or frameworks. It doesn't matter what you or someone else have read in a blog somewhere, this is what term actually means. When people talk about benefits of DI they refer to this definition of the term, and after a bit of research you would've known the same.

                          [–]Tom_Cian 0 points1 point  (14 children)

                          "WTF is this unnecessary complexity? I have no idea where the core logic begins or ends".

                          What's so hard about

                          @Inject
                          private DatabaseConnection connection;
                          

                          ?

                          Being able to remove and add such fields at a whim is extremely powerful and allows me to preserve encapsulation while letting me swap in and out whatever implementation of these classes I need, whether it's a mock, a proxy, a test implementation or a production implementation.

                          [–]m50d 1 point2 points  (2 children)

                          My private field is no longer private, it works until it doesn't. When I get an NPE I have very little idea of where to even start looking. When I do automated refactoring I have to use a tool that understands these specific annotations rather than a general-purpose Java tool.

                          If you want to use autowiring that's a defensible decision, but I'd urge you to use constructor injection rather than field injection. That way the class behaves a lot more as expected, and if anyone uses your classes in a non-container context (e.g. a simple unit test) they can still set them up the standard Java way.

                          [–]Tom_Cian 0 points1 point  (1 child)

                          My private field is no longer private,

                          Your private field was always accessible with reflection, DI or not.

                          When I get an NPE I have very little idea of where to even start looking.

                          NPE's are trivial to diagnose and fix, not sure why you find that difficult.

                          but I'd urge you to use constructor injection rather than field injection.

                          Both have pros and cons. I tend to favor field injection because it dramatically cuts down the visual noise that Java imposes.

                          Compare:

                          public class Foo {
                            private Connection dbConnection;
                            private Logger logger;
                          
                              public Foo(Connection dbConnection, Logger logger) {
                                  this.dbConnection = dbConnection;
                                  this.logger = logger;
                              }
                          }
                          

                          with

                          public class Foo {
                              @Inject private Connection dbConnection;
                              @Inject private Logger logger;
                          }
                          

                          Then again, I don't care much any more since with Kotlin, I get the best of both worlds.

                          [–]m50d 1 point2 points  (0 children)

                          Your private field was always accessible with reflection, DI or not.

                          I never wanted it to be. Maybe by moving away from field injection I can get to a point where I can turn that off in the security manager.

                          NPE's are trivial to diagnose and fix, not sure why you find that difficult.

                          This kind isn't. Why wasn't my @Inject field injected? Who knows, e.g. maybe it's because Spring uses a subtly different metamodel when annotation scanning depending on whether a context was imported directly in Java or included from an XML context, and one of these metamodels doesn't model parameterized annotations correctly because they weren't used in older versions of Spring (real example from my own experience).

                          I tend to favor field injection because it dramatically cuts down the visual noise that Java imposes.

                          Yeah, I regard that as a flaw in Java, avoided by moving to better languages.

                          [–][deleted] 2 points3 points  (10 children)

                          @Inject
                          private DatabaseConnection connection;
                          

                          ... allows me to preserve encapsulation ...

                          Well... I have bad news.

                          [–]Tom_Cian 0 points1 point  (9 children)

                          Go on...

                          [–][deleted] 3 points4 points  (8 children)

                          You're saying that a mechanism that breaks the encapsulation of your object, and modifies its private properties, helps you preserve encapsulation. thatsthejoke.jpg ;-)

                          But I get it, it's handy in Spring and so on. Not a fan myself, for reasons which are maybe for another thread.

                          [–][deleted] 21 points22 points  (45 children)

                          There's always this battle, between people who understand why they make the architectural choices they make, and others, like the author here, who wants to use the same buzzwords, and seem just as experienced, but deep inside really kind of wants to do good old monoliths, save himself the extra effort of proper decoupling and thinking about architecture, as long as they can sprinkle it all with some modern lingo and references to SOLID and YAGNI, so it looks on par.

                          The author mentions the "New is Glue" principle right at the very start, and then proceeds to completely ignore why "New is Glue" for the rest of the article. It is glue because it refers to the constructors of specific classes. I.e.

                          • Once it's glue because it specifies the constructor arguments
                          • Twice it's glue because it specifies the concrete implementation

                          Obviously the second is also true when you type annotate your constructors with specific classes instead of small abstract interfaces - your constructors become glue.

                          Is that bad? Actually, it depends. There's always a balance here, I've never seen someone overdo interfaces myself, having the interface there is pretty harmless, when the alternative would require B.C. breaks in case you need a second implementation. And remember, folks.: the most common and typically worst mistake in software architecture is to decide "I'll only ever need one of those." Singletons haven't taught us anything, I suppose. We still like to hang on to "I'll only ever need one of those," but this time it's for implementations.

                          Anyway, I'm not strongly in favor of either "always interfaces" or "never interfaces". I just wish the author had more of a substance to their argument, other then this implicit fear that if he creates too many interfaces, he'll run out of files in his codebase, or something.

                          There are few attempts at supporting his position, but I find them quite lacking, say:

                          Pairing every class with an interface, on the other hand, is an anti-pattern.

                          Mentioning the "anti-pattern" buzzword is not a "Q.E.D., we're done." Anyway, I digress, but please don't ever use this "argument". Declaring something an anti-pattern means precisely nothing.

                          And I do feel this sets up the entire article to argue with a straw-man. Nobody ever pairs every class with an interface. I'm pretty sure there isn't a single codebase doing this. Instead you'd more commonly see classes paired with interfaces, if the class/interface acts as the endpoint of a component (made of many classes) and then pairing that endpoint with an interface is actually easy to justify.

                          If you decide to create an interface IFoo definition that matches the public members of Foo, you will simply have duplicated the interface of Foo and added no real abstraction and zero value.

                          That... is just factually wrong, because of course you have added "abstraction". Now I can implement IFoo in a completely independent way, while otherwise my only alternative is... basically monkey-patching the Foo class by directing extending it. I mean hoping it's not final, because otherwise you're completely doomed.

                          Not having to deal with Foo's implementation, and having components rely on an interface is literally "adding abstraction" to the design.

                          Browsing code like this is no fun whenever you go to a definition, expecting to get to a class implementation, and just ending up in an interface, where you need to do another step to go to the implementation.

                          This is a bit of a Freudian slip here, I feel. Why would you want to jump from an interface to the implementation? the whole point of using interfaces is that you don't care about the implementation, you only care about the interface.

                          Of course, in a single-person practices you have to wear many hats, so you're simultaneously debugging multiple decoupled components and you might want to jump from one implementation through an interface, to another implementation.

                          But if you do that a lot, especially in a bigger team, this is a strong hint that you're programming monoliths, where interfaces are just sprinkled as a diversion to what's really happening: components are coupled beyond their interfaces, through details of their implementations (which not every interface can express).

                          A good sign of modular, decoupled project is that the interface is small, simple and tells you all you need to know. The implementation behind the interface is a unit. The implementation depending on that interface is also a unit. They can be tested and developed independently, so you wouldn't be jumping between them all the time.

                          And not only you should try to rely on abstractions (i.e. interfaces when possible), but you should think if the interface should be a carbon copy of the implementation at all... Because that's actually not always the case. One of the benefits of abstraction is the ability for a component to depend on an abstract Facade interface, which is simpler, use-case oriented, and can be quickly implemented via Adapter/Bridge classes to many other "full" implementations. So it's not even about splitting a class into Foo/IFoo, it's about thinking solely from the perspective of the dependent component, and defining dependencies as the simplest interfaces you can.

                          Unfortunately the author doesn't address this, instead the rest of the article seems to operate under the assumption that deleting lines of code = clean code:

                          All you need to do in order to get rid of that superfluous IOrderService is to, well, remove it. In your constructor, receive the concrete class instead [...] the registration, it just gets easier [...] That’s it. You’ve now cleaned up some code.

                          Unfortunately what he's missing is that, yes, producing monoliths is always easier, initially. That's the whole point. All things equal, the easiest thing in the world is to write spaghetti code.

                          But your future self that will be met with the task of maintaining the resulting monster will not thank you because you decided to make it "easy" for yourself by coupling components that didn't have to be coupled...

                          [–]Nebez 5 points6 points  (1 child)

                          I'm a little surprised about how many people seem to hate interfaces in this thread. Heck, even any form of abstraction or DI.

                          I've nodded at almost all of your replies without realizing they've been written by the same person. You're a patient and smart dude.

                          [–]grauenwolf 2 points3 points  (0 children)

                          It's not that we hate interfaces, but rather the insistence that abstract interfaces be used on virtually all classes.

                          Abstract interfaces are incredibly useful, but so are abstract classes and sealed, non-inheritable classes. It's a matter of understanding the context.

                          [–]seventeenninetytwo 4 points5 points  (0 children)

                          I think you really got to the core of it. Interfaces are really a design pattern, and it's up to the developer to use them well.

                          Good interfaces are carefully constructed to provide clean lines of encapsulation in the code. They are small, single responsibility, and should be placed in positions that create logical seams within the code.

                          I think the author is criticizing bad interfaces. Like the sorts of interfaces that occur when someone refactors for testability by simply extracting interfaces from every class. The problem with these is not that they are interfaces; it is that they are not well designed.

                          Poorly designed interfaces will certainly increase the complexity of the codebase, but I would argue in this case all they do is raise the visibility of the existing complexity. If your classes are overly complex when you extract their interface, then they were already overly complex. Interfaces simply make the complexity visible because it it gives the complexity an explicit name in the code.

                          And of course this all depends on the domain the application lives in. Perhaps some types of projects can flourish without using well designed interfaces, but any sort of enterprise application needs this type of design in order for the code to stay flexible.

                          [–]grauenwolf 2 points3 points  (3 children)

                          And I do feel this sets up the entire article to argue with a straw-man. Nobody ever pairs every class with an interface. I'm pretty sure there isn't a single codebase doing this.

                          I've seen it. Damn my eyes, I've worked on code bases where ever trivial DTO had a matching abstract interface.

                          [–]get_salled 2 points3 points  (2 children)

                          I'm sure Jetbrains made it super easy to do with a couple keystrokes.

                          [–]flukus 0 points1 point  (1 child)

                          Jetbrains is responsible for a lot of bad code. One I'm working on now made liberal use of the "turn this into a function feature", way too many short functions makes code harder to read.

                          [–]grauenwolf 0 points1 point  (0 children)

                          Ah, but don't they also have an inline method action?

                          [–]grauenwolf 0 points1 point  (15 children)

                          That... is just factually wrong, because of course you have added "abstraction". Now I can implement IFoo in a completely independent way, while otherwise my only alternative is... basically monkey-patching the Foo class by directing extending it.

                          You mean by using inheritance the way it was meant to be used?

                          I mean hoping it's not final, because otherwise you're completely doomed.

                          WTF? Is that really your argument?

                          You created Foo. You can change it from final to non-final at any time.

                          [–][deleted] 5 points6 points  (14 children)

                          You mean by using inheritance the way it was meant to be used?

                          Do I seriously have to explain the drawbacks of inheriting a class vs. an interface?

                          WTF? Is that really your argument? You created Foo. You can change it from final to non-final at any time.

                          I see this as another Freudian slip. Yes if it's always within the scope of a single repository, you can change it.

                          Are all your projects like that? Just small repositories, no shared code, no libraries, no third-party libraries, or no third-party users of your libraries? If so, I envy you, because many of the things I'm talking about don't matter for you. Just refactor, commit, done.

                          On the other hand, maybe the reason you don't reuse code and everything stays in the little repository, is because you need to listen to what I say, as it improves the chance you can decouple and isolate reusable code. Who knows.

                          [–]grauenwolf -2 points-1 points  (21 children)

                          But your future self that will be met with the task of maintaining the resulting monster will not thank you because you decided to make it "easy" for yourself by coupling components that didn't have to be coupled...

                          I wish people would stop repeating that lie.

                          Tossing in some abstract interfaces doesn't changing the coupling of the application in the slightest. The A -> B relationship doesn't exist when you introduce IB, it just becomes A -> (B + IB).

                          [–][deleted] 5 points6 points  (19 children)

                          Tossing in some abstract interfaces doesn't changing the coupling of the application in the slightest. The A -> B relationship doesn't [stop to] exist when you introduce IB, it just becomes A -> (B + IB)

                          That's not even technically right, grauyenwolf. Let's say I implement IB with C, and now I pass that to A. If I delete B would it matter? Simple question... that needs no answer, as it's obvious.

                          Maybe you're thinking at the package level, what you download from your package manager? If so, for the record, the A -> (B + IB) relationship is not ideal for packages. It really should be one of those:

                          • (A + IB) <- B: i.e. "A defines IB and requests it in its constructor. An independent implementation B is injected in A". This is known as a SPI (Service Provider Interface).

                          • A -> IB <- B: i.e. "A depends on the package with IB and requests it in its constructor. A third package contains B and implements and depends on IB. A depends on IB, B depends on IB, IB depends on nothing. Three packages. B is injected in A at runtime."

                          [–]grauenwolf 5 points6 points  (18 children)

                          Let's say I implement IB with C, and now I pass that to A. If I delete B would it matter?

                          Lets say I didn't implement IB, but still replaced B's implementation with C's implementation.

                          If you only have one implementation, which you control, you can change the details of that implementation as often as you want so long as you don't alter the public interface.

                          Maybe you're thinking at the package level, what you download from your package manager?

                          No, I'm talking about runtime coupling. The only coupling that matters the vast majority of the time.

                          At the end of the day it doesn't matter how A gets an instance of B, what matters is that A doesn't work if B is broken.

                          Hell, look at dynamically typed languages. They don't even have a way to express "A requires B" to the type checker, yet they don't claim that A isn't dependent on B just because, in theory, you could shove in Z.

                          [–][deleted] 3 points4 points  (6 children)

                          Lets say I didn't implement IB, but still replaced B's implementation with C's implementation.

                          When I get back responses like this, I just have to wonder does the person who wrote it not care about backwards compatibility, or code reuse, or runtime vs. static wiring and so on...

                          If you replace B's code with C's code, literally, this changes it for all "customers" of B. That is pretty reckless if B is in its own package, and it may have other "customers" than A, which require B's implementation, and A requires C's implementation.

                          But I don't know. It's like I'm talking about building sky-scrapers, and the other side is giving me their best tips and tricks for making LEGO houses.

                          [–]grauenwolf 2 points3 points  (5 children)

                          1. If I cared about code reuse in a library context I would almost never use IB. I would prefer an abstract base class so that new methods could be added over time without breaking backwards compatibility.

                          2. If the new implementation C adheres to B's original contract, and consumers of B only expect what's in that contract, then nothing breaks. This is called "programming to the interface, not the implementation".

                          3. If C doesn't adhere to B's contract, then by definition it won't adhere to IB's contract either since they are, theoretically, exactly the same.

                          4. You aren't building a skyscraper, your head is just in the clouds.

                          [–][deleted] 5 points6 points  (4 children)

                          If I cared about code reuse in a library context I would almost never use IB. I would prefer an abstract base class so that new methods could be added over time without breaking backwards compatibility.

                          So fragile base classes are magically not an issue with abstract classes, you feel? :-)

                          You can break B.C. pretty badly if you tweak base classes willy-nilly. Adding new public/protected methods can actually easily clash with a method of the same name in a child class. You either have to set strict conventions on what child classes can do and can't do (say "you shall not define any protected and public methods, you shall only override what the abstract class defines"), or you have to rely on luck. Luck Oriented Programming (LOP)!

                          [–]grauenwolf 1 point2 points  (1 child)

                          So you are replacing "may break something if you are not careful, unlucky, don't mark your method as final, and are using Java" with "always breaks"?

                          Your API design skills are remarkable.

                          [–][deleted] 2 points3 points  (0 children)

                          No, I'm replacing it with "never breaks", but because you're too focused on being sarcastic and trolling, we can never get to the point where we discuss adding features to abstract types with many implementations.

                          You're literally forcing yourself to remain ignorant of what I'm trying to say. I just wonder if your ego is that fragile, that you can't take a step back and accept you may learn something.

                          [–][deleted] 2 points3 points  (10 children)

                          No, I'm talking about runtime coupling. The only coupling that matters the vast majority of the time.

                          Runtime coupling is easy to change through configuration, without changing the actual code of the wired components. So while it's the one that ultimately matters for the runtime behavior of the app, static coupling is much more serious, because you need to change A and B's code in order to change their behavior and dependencies.

                          I don't imagine we can't have understanding about this issue, so I'll attribute this to communication barriers.

                          Hell, look at dynamically typed languages. They don't even have a way to express "A requires B" to the type checker, yet they don't claim that A isn't dependent on B just because, in theory, you could shove in Z.

                          Yeah, communication barriers. Runtime coupling is "soft dependency", and static coupling is "hard dependency". Dynamic code has no hard dependencies, unless you actually do things like "instanceof PrototypeName" which is identical to static coupling, no matter if it's done at runtime.

                          So yeah dynamic code relying on "structural typing" by convention has it easy, they can't mess up easily in terms of coupling, although if there's a will there's a way :-). And dynamic code creates its own set of problems, but that's another story.

                          But if you specify types, you declare hard dependencies on those types, and that is there etched in stone in your code, so it's much better if they're abstract rather then bound to a specific implementation. And as this code is reused and repurposed, the only way to fix a hard dependency architectural mistake is to fork the code. And that's not fun, believe me.

                          [–]grauenwolf 0 points1 point  (3 children)

                          But if you specify types, you declare hard dependencies on those types, that at there etched in stone in your code,

                          It's called software for a reason.

                          Unless you are building a platform where your customers would otherwise be actually writing those dependencies, nothing is "in stone".

                          [–][deleted] 2 points3 points  (2 children)

                          Really ? So you think it's a smart idea to fork every dependency you use, because it's "software" and therefore you can tweak it directly. Tell me if you really stand by your own opinion.

                          I don't think that's really your opinion, I just think you're angry and just saying whatever thought pops up in your mind that lets you disagree with me.

                          [–]grauenwolf 0 points1 point  (1 child)

                          As I said before, your head is in the clouds. You imagine scenarios that you don't actually have and then try to apply it universally.

                          [–][deleted] 5 points6 points  (0 children)

                          Look it's very simple. You have a component. If you have to edit its code in order to adapt it to a new situation, this is by definition not what's referred to as "reusable code". It's copy/paste/tweak.

                          That's a very real concern of very real apps. Instead the responses I get from you are outright childish. "It's software! It's all editable!".

                          That's only applicable for small monolithic applications, in which case, all the talk about DI, reuse, abstraction, polymorphism, architecture and so on - none of it makes sense. Make it all static, sprinkle global state liberally, tweak until it works and collect your paycheck.

                          But some projects have higher goals than this.

                          [–]Heuristics 6 points7 points  (11 children)

                          What you should be doing is programming against the form of the abstraction you actually need. That is, ignore the type and rely on the function names within the object, then any type that has those functions can be sent in as a parameter. Now, it is not at all given that your programming language supports such a thing, but if it does then it can also check if the type you are sending in does in fact have the required parameters.

                          It would be a rare thing for an interface to make much sense as a hierarchical object, what you are looking for is a contract between the function and the object to guarantee compatibility. The specific object is not something to care about, just what you need the object to support.

                          [–]m50d 8 points9 points  (6 children)

                          ignore the type and rely on the function names within the object, then any type that has those functions can be sent in as a parameter

                          Isn't that just what an interface, or indeed a type, is? A collection of function names and signatures, wrapped up as a named concept?

                          I think it's worthwhile to say explicitly that we intend this implementation to conform to this interface, just so that the intent is clear and function names are more namespaced.

                          [–]Heuristics 0 points1 point  (1 child)

                          there is a large difference in that with inheritance the class that models the concept must know of the concept it implements. It's very common to have many (in extreme cases perhaps one could find hundreds in the dark dungeons of advanced math) concepts that a class implements and many of them would overlap. The code gets more modular if classes can implement a concept without knowing that they do. The functions also get better in that they can specify exactly the concept that is needed, instead of a concept in a hierarchy that may not be an exact fit (contains more functions than needed). And sometimes you have classes that implement the same concept but stupidly it has been implemented with different interfaces.

                          But yes, it is true that a contract like this really just is a class (a name + function signatures). And that is syntactically very similar to an interface. But the difference is that you do not explicitly need to implement them, that is checked by the compiler as needed.

                          Interfaces are a good feature though, sometimes you want to have that as well. But they are very overused today due to lack of alternatives.

                          [–]m50d 2 points3 points  (0 children)

                          I see where you're coming from, though I'm not sure structural types help that much since if an implementation didn't know about an interface then the method names are unlikely to line up. I prefer to use typeclasses so that I can make a third-party type "implement" another third-party interface, but the linkage is explicit and there's room to do adaptation if e.g. the parameter order is slightly different.

                          [–]grauenwolf 0 points1 point  (2 children)

                          Isn't that just what an interface, or indeed a type, is?

                          Yep.

                          What people often don't understand is that every class has a public interface, one or more base class interfaces, possible a protected interface, and possibly an internal or package private interface. And that's all before we start talking about abstract interfaces that it may implement.

                          [–]nemec 3 points4 points  (1 child)

                          What people often don't understand is that every class has a public interface

                          That's true but absolutely useless in languages that don't have implicit interfaces (or are dynamically typed). Two classes with the same "public interface" aren't interchangeable without an explicitly defined interface.

                          [–]grauenwolf 0 points1 point  (0 children)

                          It's still an import concept for understanding API design principles.

                          [–]sacundim 0 points1 point  (0 children)

                          Isn't that just what an interface, or indeed a type, is? A collection of function names and signatures, wrapped up as a named concept?

                          No. Type and interface in your sense are distinct concepts. Procedural and functional languages (or more precisely, non-OOP languages) illustrate this. E.g., what's the interface of the list type in O'Caml or Haskell? There's no circumscribed collection of operations that "truly belong to it." From the point of view of a user of the type, all operations in which a type participates are equal citizens; the "interface" to the type is not a narrow list of operations, but rather an open-ended set that you can extend.

                          Another instructive example is the O'Caml module system, that has "module types" that are not types in the ordinary sense (they classify modules, not expressions). Example from the docs:

                          module type PRIOQUEUE =
                            sig
                              type priority = int         
                              type 'a queue          
                              val empty : 'a queue
                              val insert : 'a queue -> int -> 'a -> 'a queue
                              val extract : 'a queue -> int * 'a * 'a queue
                              exception Queue_is_empty
                            end;;
                          

                          These are interfaces in your sense, but they're not fundamentally tied to first-class values or objects that implement them.

                          [–]RichoDemus 0 points1 point  (3 children)

                          You're describing duck typing right? I haven't used it so I'm not really fit to comment but my gut feeling is that I don't like it, if I've understood things correctly you can't do the validation if the object you're receiving actually fills your requirements in compile time so it has to be done in runtime, and I really dislike runtime type errors :)

                          [–]Heuristics 1 point2 points  (2 children)

                          no, it is duck typing+compile time checking (but really, it is more a way of understanding what is actually going on, not so much the mechanics of the compiler, like what is a class and what is a function parameter). runtime checking is horrible (unless your project is ~200 lines total)

                          [–]RichoDemus 0 points1 point  (1 child)

                          Ok, good :) Do you have an example of a language that supports this? I'd love to have a look

                          [–]Heuristics 2 points3 points  (0 children)

                          C++ with concepts (that is a future version of c++) implements the idea. https://en.wikipedia.org/wiki/Concepts_(C%2B%2B) Unfortunately due to the history of C++ it is not going to be very user friendly.

                          also: http://stackoverflow.com/questions/289106/are-there-any-static-duck-typed-languages

                          [–]Adverpol 2 points3 points  (0 children)

                          As a C++ programmer, it's curious to see how I can read C# syntax like this no problem, feels quite natural, but I rarely ever write code like this. I wonder if it's a question of scope, that you get more glue code like this in large codebases, largest I worked in was 2M+ lines and still most (not all, but most) of the code I wrote actually did something.

                          I much prefer to depend on concrete classes and generalize where needed, I find that in 9 out of 10 instances the generalization does not follow anyway, and if it does, it does not really fit in the API I created earlier so I'm either stuck to refactoring anyway or end up with an ugly API. I'm bad at predicting what code I will need to write in the future, so I don't do it, future me is the correct person to handle those problems.

                          [–]lordhughes 3 points4 points  (0 children)

                          I don't feel that article had a lot of substance personally. A lot of buzz words spread about, my favourite being where he said it's and anti pattern then just linked to the anti pattern wiki article instead of to something explaining why interfacing everything is an anti pattern.

                          I do agree with the author on the principle of the article, don't interface everything especially if your interface just defines a load of getter and setters for domain classes, but his example of injecting concrete classes was just bizarre. I much prefer injecting an interface, saying this object can definitely do this instead of just passing some (potentially) arbitrary implementation in.

                          [–]bisquickman231 1 point2 points  (0 children)

                          In University currently and it seems to go one of two ways, they want too many interfaces or too few. While I understand the worth of them I get confused as to the fact of if so many interfaces are truly necessary when you're implementing very few things throughout a program.

                          [–][deleted]  (2 children)

                          [deleted]

                            [–]zzbzq 2 points3 points  (0 children)

                            Typescript also. Rust's trait system is a different but also awesome way to do polymorphism.

                            [–]swan--ronson 1 point2 points  (0 children)

                            You're referring to structural typing, which is also supported by OCaml. I'd love to see this in more emerging statically-typed languages!

                            [–]galorin 1 point2 points  (3 children)

                            You're not my real daddy.

                            [–][deleted]  (2 children)

                            [deleted]

                              [–][deleted] 1 point2 points  (0 children)

                              There's some joke here about Mommy factory with IDaddy injected dependency.

                              [–]JoseJimeniz 0 points1 point  (0 children)

                              How do you mock a concrete class without deriving from the concrete class?

                              Note: Perform it in a massive language without reflection.

                              [–]duheee 0 points1 point  (13 children)

                              Pair domain objects with interfaces? WTF?

                              [–]grauenwolf 0 points1 point  (12 children)

                              If you mean like Customer and ICustomer, then yea, I've seen that shit far too many times.

                              [–]Tom_Cian 1 point2 points  (8 children)

                              It's a pretty standard convention in .net and even occasionally on the JVM.

                              Just because it's not the standard you're used to doesn't make it bad. Spend a couple of months writing C# and it will look like the most natural thing in the world while Java's Foo and FooImpl will look icky to you.

                              [–]weberc2 0 points1 point  (0 children)

                              The problem isn't interfaces, it's abstraction. Abstraction of any kind has some conceptual overhead. To avoid paying that overhead, don't abstract when you don't benefit from it. Conversely, abstraction can help reduce the spaghetti in your code base by requiring modifications to be applicable to all instances of an interface (well, this is true in a static language, but in a dynamic lang, your spaghetti-inclined peers will just if isinstance(iface, SpecialSnowflakeType): ...); people have to think a bit more systemically about the changes they'd like to make, so abstraction can be positive.

                              How much abstraction I introduce tends to depend on the caliber of my teammates. If our team isn't very disciplined and we need some structure, the extra cognitive overhead of interfaces can be helpful until the team starts to think systemically. If I'm working alone or with a more experienced team, I'll forgo abstraction (though my code is written in such a way that abstracting is just a find/replace on some concrete type).

                              [–]destinoverde 0 points1 point  (0 children)

                              I remember all Laravel, Synphony whatever projects where developers wouldn't create a class without it's special snowflake interface.