服务和DAO始终实现接口

时间:2013-08-27 23:33:28

标签: java spring spring-mvc

在我看过的所有MVC项目中,“service”和“DAO”类总是实现自己的接口。但几乎所有时间,我都没有看到过这种界面有用的情况。

在这些情况下是否有任何理由使用接口?不在“服务”和“DAO”类中使用接口可能会导致什么后果?我无法想象会有什么后果。

5 个答案:

答案 0 :(得分:3)

Spring是一个Inversion of Control容器。从某种意义上说,这意味着您使用的类的实现不会落在应用程序上,而是落在其配置上。如果您的班级需要UserRepository来存储User个实例,那就像是

class UserService {
    @Autowired
    private UserRepository userRepository;
}

interface UserRepository {
    List<User> getUsers();
    User findUserBySIN(String SIN);
    List<User> getUsersInCountry(Long couyntryId);
}

你会为它宣布一个bean

<bean class="com.myapp.UserRepositoryHibernateImpl">
   ...
</bean>

请注意,此bean是UserRepositoryHibernateImpl,它将实现UserRepository

在世界未来的某个时刻,Hibernate项目停止受到支持,您确实需要一个仅在Mybatis上可用的功能,因此您需要更改实现。由于您的UserService类正在使用以接口类型声明的UserRepository,因此只有接口上可见的方法对类可见。因此,更改userRepository的实际多态类型不会影响客户端代码的其余部分。您只需要更改(不包括创建新类)

<bean class="com.myapp.future.UserRepositoryMyBatisImpl">
   ...
</bean>

您的申请仍然有效。

答案 1 :(得分:2)

有许多论据支持接口,请参阅Google。

我可以添加其他人提到的观点:

  1. 想象一下,您将DAO实现从Hibernate更改为iBatis。对接口而不是实现的依赖将对服务层有很大帮助。
  2. 如果您使用AOP或使用JDK动态代理的代理,那么您的类必须实现接口。这不是CGLIB的情况。
  3. 在服务层,如果你想将你的方法发布给其他客户端来调用,给它们“作为合同的接口”会更有意义而不是实现。
  4. 如果你想从daos.jar中分离services.jar,那么你的daos上的接口会在daos.jar更改的情况下从重新编译中保存services.jar。
  5. 简而言之,拥有接口真是太棒了!

答案 2 :(得分:0)

基于接口的实现有助于在测试套件中模拟它们。在我们的项目中,在测试服务层时,我们模拟DAO并提供硬编码数据,而不是真正连接到数据库。同样的论点也适用于服务层。

答案 3 :(得分:0)

尽早使用接口可使您的应用程序可以扩展,并且不使用接口会影响应用程序的可伸缩性。

答案 4 :(得分:0)

我最近一直在问自己一个完全相同的问题,感觉创建一个接口,即使我知道有一个单独的实现类是愚蠢的,并增加了膨胀(每个Java程序员尝试更实用的语言会知道这种感觉)。这是另一个编译模块,通常只是为了满足一个人的内心教条主义者。

Spring似乎已经演变成面向模块/组件的框架,程序员只创建块,框架将它们组合在一起。这就是为什么让多个bean匹配标准是一个问题并使事情变得复杂(你最终使用的限定符会破坏DI的目的)。程序员自然会尝试避免类型歧义,以最大限度地减少所需配置的数量,理想情况下,任何给定的块只适合一个“插槽”。

在我看来,DI的最大优势并非它可以轻松地更改实现(通过简单地更改配置XML中声明的类的类型),但它允许更容易地分离依赖项,从而更容易在分离中测试每个组件。你不需要一个子接口。

由于对类进行逆向工程以提取其接口将是一个纯粹的机械任务,我不担心“如果我需要添加另一个实现怎么办?”参数。

免责声明:中小型应用程序开发人员的意见;我确信大型项目的情况会发生变化。