I am new to spring Mvc and in a lot of tutorials, I found there is a Dao interface like this
public interface StudentDAO {
public List<Student> getStudents();
public void addEntry(Student student);
public void updateEntry(Student student);
public void deleteEntry(Student student);
public Student getStudentById(int id);
}
and also services like this
public interface StudentService {
public List<Student> getStudents();
public void addEntry(Student student);
public void updateEntry(Student student);
public void deleteEntry(Student student);
public Student getStudentById(int id);
}
And there are implementations for these interfaces.
My question is why we need interfaces rather than direct implementation classes?
In theory, it creates interfaces to decrease the coupling. In other words you create interfaces that are the communication contracts. And with that you can have more of an implementation for the same contract. Example: In PersonDao you can have implementation with hibernate and one with native SQL. With that in places where you used, you only inject interace and CDI itself solves the implementation, then you easily change the implementation without affecting the places where it is used interfaces.
In practice in my projects, depending on the situation, do not create the interfaces, but I will emphasize, it depends on the project. Example: A DAO in the majority of the time it never changed its implementation, that is, I see no need to create the interfaces in these cases directly implement the concrete classes.
The post Jiri Tousek is an example for the use of interfaces. However in my tests, I always use the complete flow, including the database.
Perhaps the simplest concrete illustration for the need is testing.
With the DAO interface, you can test your application's logic without the need to have a DB running that's accessible from the machine running tests, simply by swapping your DAO implementation for a dummy one during tests. That dummy implementation can then provide consistent data for tests that doesn't change between test runs, cannot be overwritten in DB by accident, is versioned in you Git/SVN/whatever etc.
In general, this is part of the Program to an interface, not an implementation design principle.
In my experience, this separation of interface vs. implementation is a good idea even if you're never going to have multiple implementations, because it encourages programmers to think more deeply about the contract of the class.
Note that the principle is not universally accepted, here are some counter-arguments for example.
I'm glad to see someone questioning that practice.
Spring Framework introduced long time ago the pattern of defining interfaces for their managed service / DAO beans. I think that practice was introduced due to limitations in the technology they used to create dynamic proxies.
When a Spring-managed bean is defined, the framework creates a proxy to the underlying instance with the purpose of decorating it with cross-cutting functionality using AOP techniques. Apparently, the tools they used to implement those proxies in the early versions of Spring Famework required an interface to create the proxy out of it.
This requirement no longer holds in the latest versions of Spring Framework and you're safe to dispose of those useless interfaces.
The reason for ease of testing does not hold nowadays, either, as mocking frameworks like Mockito are also capable of mocking concrete classes.
In addition, you can use the @Primary annotation to replace the real implementation with a custom mock in a testing context.
For those reasons, I would scrap interfaces for internal service and DAO classes that will never have multiple co-existing valid implementations.
Keep interfaces for design patterns that really need them.
if you are doing project it includes some database so you must define function in interface in this way Which you use is easily seen.