I've worked/seen a few spring-hibernate web application projects having as many interfaces as there are actual service and dao classes.
I always thought that these two as the main reasons for having these single implementation interfaces:
Spring can wire actual implementation as dependencies in a given class (loose coupling)
public class Person { @Autowired private Address address; @Autowired private AccountDetail accountDetail; public Person(Address address, AccountDetail accountDetail) { // constructor
While unit testing, I can create mock classes and test a class in isolation.
Address mockedAddress = mock(Address); AccountDetail mockedAccountDetail = mock(AccountDetail); Person underTestPerson = new Person(mockedAddress, mockedAccountDetail); // unit test follows
But, of late, I realized that:
Spring can wire concrete implementation classes as dependencies:
public class Person { @Autowired private AddressImpl address; @Autowired private AccountDetailImpl accountDetail; public Person(AddressImpl address, AccountDetailImpl accountDetail) { // constructor
Mock frameworks like EasyMock can mock concrete classes as well
AddressImpl mockedAddress = mock(AddressImpl); AccountDetailImpl mockedAccountDetail = mock(AccountDetailImpl); Person underTestPerson = new Person(mockedAddress, mockedAccountDetail); // unit test follows
Also, as per this discussion, I think the summary is that within a single app, interfaces are mostly overused probably out of convention or habit. They generally make best sense in cases where we are interfacing with another application for example slf4j used by many apps around the world. Within a single app, a class is almost as much an abstraction as an interface is.
So, my question is why do we still need Interfaces and then have single implementations like *ServiceImpl and *DaoImpl classes and unnecessarily increase our code base size. Is there some issue in mocking concrete classes that I’m not aware of.
Whenever I've discussed this with my team-mates, only answer I get is that implementing service and dao classes based on interfaces is THE DESIGN everybody follows - they mention about spring best practices, OOP, DDD etc. But I still don't get a pragmatic reason behind having so many interfaces within an isolated application.
Implementing an interface allows a class to become more formal about the behavior it promises to provide. Interfaces form a contract between the class and the outside world, and this contract is enforced at build time by the compiler.
If, as the OP claims, you could just as easily write the program without the interface your tests would be just as valid or invalid depending only upon the choices made by the architect.
Using Interfaces allows your classes to extend from some other classes if required. Your Interfaces can have multiple implementations and you can switch between any of them without changing the client code.
Yes, it is mandatory to implement all the methods in a class that implements an interface until and unless that class is declared as an abstract class.
There are more advantages to interfaces - As in proxying . If your class implements an interface , JDK dynamic proxies will be used by default for AOP . If you use the implementations directly, you'll be forced to use CGLIB proxies by making proxy-target-class=true . These require byte code manipulation unlike JDK proxies .
read here for more on this .
Read another discussion at what reasons are there to use interfaces (Java EE or Spring and JPA) for more info .
It's a very controversial subject. In brief, there's none—at least for you, the developer.
In EJB2 world, the Home and Remote interfaces were a must, and were exactly for a reason @AravindA mentions: proxies. Security, remoting, pooling, etc. all could be wrapped in a proxy, and provide the services requested strictly within standard library (as in DynamicProxy
).
Now that we have javaassist
and cglib
, Spring (Hibernate, EJB3 if you prefer) are perfectly capable of instrumenting your classes as framework developer likes. Problem is, what they do is a very annoying thing: they usually request you to add a no-parameter constructor.—Wait, I had parameters here?—Nevermind, just add the constructor.
So interfaces are here to maintain your sanity. Still, it's strange, a no-argument constructor for a class with proper constructor is not something that makes a sense to me, right? Turns out (I should've read the spec, I know) that Spring creates a functional equivalent of an interface out of your class: an instance with no (or ignored) state and all the methods overridden. So you have a "real" instance, and a "fake interface" one, and what fake interface does is, it serves all the security/transactional/remoting magic for you. Nice, but hard to understand, and looks like a bug if you haven't taken it apart.
Moreover, if you happen to implement an interface in your class, (at least some versions of) Spring suddenly decides you were going to proxy this interface only, and the application just doesn't work for no apparent reason.
Thus, so far the reason is, safety and sanity. There are reasons why it is a good practice—but from your post, I see you already read all of those. The most important reason I can see today is the WTH/minute metric, especially if we're talking about newcomers to your project.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With