Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why always have single implementation interfaces in service and dao layers?

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:

  1. 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 
  2. 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.

like image 508
haps10 Avatar asked Jan 19 '12 06:01

haps10


People also ask

Why do we need interface in service layer?

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.

What is the point of having every service class have an interface?

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.

Why do we need service interface in spring?

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.

Is it mandatory to implement all the methods of an interface?

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.


2 Answers

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 .

like image 72
Aravind A Avatar answered Oct 14 '22 14:10

Aravind A


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.

like image 34
alf Avatar answered Oct 14 '22 15:10

alf