Why do there always exist uniform implementation interfaces in the service and Tao?

I have worked / seen several spring-hibernate web application projects having so many interfaces that there are actual service classes and tao.

I always thought that these two are the main reasons for having these common implementation interfaces:

  • Spring can bind the 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 
  • During unit testing, I can create mock classes and test the class in isolation.

     Address mockedAddress = mock(Address); AccountDetail mockedAccountDetail = mock(AccountDetail); Person underTestPerson = new Person(mockedAddress, mockedAccountDetail); // unit test follows 

But lately, I realized that:

Spring can use specific implementation classes as dependencies:

 public class Person { @Autowired private AddressImpl address; @Autowired private AccountDetailImpl accountDetail; public Person(AddressImpl address, AccountDetailImpl accountDetail) { // constructor 

Layout frameworks like EasyMock can also mock specific classes.

 AddressImpl mockedAddress = mock(AddressImpl); AccountDetailImpl mockedAccountDetail = mock(AccountDetailImpl); Person underTestPerson = new Person(mockedAddress, mockedAccountDetail); // unit test follows 

Also, according to this discussion, I think the summary is that in one application the interfaces are mostly abused, probably due to convention or habit. As a rule, they make better sense when we interact with another application, for example slf4j, used by many applications around the world. In one application, a class is almost the same abstraction as an interface.

So, my question is why we still need interfaces, and then we have uniform implementations, such as * ServiceImpl and * DaoImpl classes and unnecessarily increase the size of the code base. Is there any problem in mocking specific classes that I don't know about.

Whenever I discussed this with my teammates, the only answer I get is that implementing the services and dao classes based on the interfaces - these are DESIGNs that follow them - they mention spring best practices, OOP , DDD, etc. But I still don't understand the pragmatic reason for having so many interfaces in an interface.

+25
java spring design-patterns mocking domain-driven-design
Jan 19 2018-12-12T00:
source share
2 answers

There are more advantages to interfaces - as well as to proxies. If your class implements an interface, JDK dynamic proxies will be used by default for AOP. If you use the implementations directly, you will be forced to use the CGLIB proxy by creating proxy-target-class = true. They require byte code manipulation, unlike JDK proxies.

read here to learn more about this.

Read another discussion of what reasons can be used to use interfaces (Java EE or Spring and JPA) for more information.

+14
Jan 19 '12 at 7:01
source share

This is a very controversial issue. In short, not there - at least for you, the developer.

In the EJB2 world, the Home and Remote interfaces were mandatory, and it was for some reason that @AravindA mentions: proxies. Security, remote access, pooling, etc. All can be wrapped in a proxy server and provide services requested strictly in the standard library (as in DynamicProxy ).

Now that we have javaassist and cglib , Spring (Hibernate, EJB3, if you prefer), do a great job with your classes, as the framework developers like. The problem is that they do very unpleasantly: they usually ask you to add a constructor without parameters. - Wait, did I have parameters here? - Incredible, just add a constructor.

Thus, the interfaces are designed to maintain your sanity. However, this is strange, a constructor without arguments for a class with an appropriate constructor is not something that makes sense to me, is it? It turns out (I should have read the specification, I know) that Spring creates the functional equivalent of an interface from your class: a stateless instance (or ignored) and all overridden methods. So you have a “real” instance and a “fake interface”, and what fake interface it does, it serves as all your protection / transaction / deletion. Nice, but hard to understand, and looks like a mistake if you haven’t figured it out.

In addition, if you have to implement an interface in your class, (at least some versions) Spring will suddenly decide that you are going to proxy only this interface, and the application simply does not work for no apparent reason.

Thus, the reason is still that security and sanity. There are reasons why this is good practice, but from your post, I see you have already read all this. The most important reason that I see today is the WTH / minute indicator, especially if we are talking about new participants in your project.

+14
Jan 19 '12 at 7:59
source share



All Articles