I've been reading about DI and best practices, and still haven't found the answer to this question. When should I use interfaces?
- Some developers suggest to add interface for every object that is being injected. This would make a modular application.
- Some other are against this.
So my question is which one is correct?
EDIT:
Below are the two sides, I still don't see the advantage of using interfaces. In both cases I can easily mock classes, and change the implementations
Using interfaces
bind(IUserStorage.class).to(UserStorage.class);
// Unit test
bind(IUserStorage.class).to(Mock(UserStorage.class));
Not using interfaces
bind(UserStorage.class).to(UserStorage.class);
// Unit test
bind(UserStorage.class).to(Mock(UserStorage.class));
Your question states "some developers [are for this]" and "some developers [are against this]", so there is no right answer. But this is why I agree that interfaces are overused
If you are creating a library, choosing when to use interfaces is important. It is harder to create a maintainable contract when you don't control how your code is consumed.
If, however, you are creating an application, it less likely to require an interface, because the public interface of a class can serve as the maintainable contract to consuming code. Let's say version 1 looks like this:
You don't even need refactoring tools to change it to this:
Then you can easily use refactoring tools to rename the interface to
IUserStorage
.So when you are writing non-library code, you can usually get away with a class until you need swappable implementations, decorators, etc. You should use an interface when the public interface of the class does not suit your needs. (For example, see the interface segregation principle)
In short - having an interface that is 1:1 with a class is unnecessary indirection in application code.
I can't believe using interfaces is againt OOP principles!
I would definitely use interfaces in this scenario. It means you're loosely coupling your components and can easy mock and/or substitute alternatives. Lots of DI frameworks will use the interfaces in order to provide additional functionality (e.g. create proxy objects mapped to the real objects, but with additional features).
As such I would try and use interfaces for all but the most trivial of injected objects. At some stage you're going to want to make use of substitutability, framework code generation etc. and retrofitting interface usage is an additional pain that it's easy to avoid at the beginning of a project.
Interface based design is the cornerstone of IoC, here is a short description of Interface-based design (Sorry that I'm referencing my own blog, but I just finished an article about this, it was an extract from my MS Thesis):
Once you mix interface design with IoC you obtain the following benefits:
To answer your question, I would use interfaces for different types of modules. For example, one per service or repository.
I do not create interfaces for controllers or Model classes (MVC apps).
All this, as a side effect, facilitates testing.
If you use interfaces or at least abstract/inheritable classes you can change the behaviour of the program by an easy exchange of the implementation (inject another class) in the DI/IoC config. Using interfaces is a good practice (imho). This is especially very important if you are writing UnitTests which needs mocks. It is much harder to write UnitTests with a good coverage (not to say impossible in most "real world" cases) if you're not using interfaces.
I think you should use an interface if there might be a chance that the injected part could change. It should be easy to extend your implementation, see Open-Closed-Principle. => This will require the exchange of modules/parts/implementations... ask yourself what would happen if your class has no virtual functions to override and you are forced to change the implementation.
I would use interfaces at least for the public classes / parts of your code (the parts other programmers would use).
Having a look at your sample. The problem is at the wiring part and not only the binding of a class as (default) implementation of an interface (binding works, but wiring could break).
For example if you have 2 implementations (C# sample here, should be the same in Java etc., too):
Depending on your IoC it should be easy to wire an instance of MyStorageClient to your binding of IUserStorage.
But if your MyStorageClient is strongly forced to use DB already...
... it is imposible to wire it up with the UserStorageTextFile class except the UserStorageTextFile is inherited from UserStorageDB... but why should you have a dependency to e.g. Oracle drivers (required by UserStorageDB) if you only want to write a simple text file?
I think the sample is clear enough and shows up the benefits of using interfaces...
but if not... try to do this: