9

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

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

4

5 回答 5

3

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

我可以补充其他人提到的几点:

  1. 想象一下,您将 DAO 实现从 Hibernate 更改为 iBatis。依赖于接口而不是实现将对服务层有很大帮助。
  2. 如果您使用 AOP 或使用 JDK 动态代理的代理,那么您的类必须实现接口。这不是CGLIB的情况。
  3. 在服务层,如果你想将你的方法发布给其他客户端调用,给它们“接口作为合同”会比实现更有意义。
  4. 如果您想将 services.jar 与 daos.jar 分开,那么在您的 daos 上拥有接口可以避免重新编译 services.jar,以防 daos.jar 发生变化。

总之,有接口就好!

于 2013-08-28T03:36:26.663 回答
3

Spring 是一个控制反转容器。从某种意义上说,这意味着您使用的类的实现不取决于应用程序,而是取决于其配置。如果您有一个需要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>

请注意,这个 beanUserRepositoryHibernateImpl将实现UserRepository.

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

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

并且您的应用程序仍然有效。

于 2013-08-27T23:45:13.677 回答
0

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

于 2013-08-27T23:37:40.773 回答
0

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

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

在我看来,DI 的最大优势不是它可以很容易地更改实现(通过简单地更改配置 XML 中声明的类的类型),而是它允许更容易地分离依赖关系,从而更容易分离地测试每个组件. 为此,您不需要一个子接口。

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

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

于 2013-08-28T23:05:58.877 回答
0

尽早使用接口可以使您的应用程序具备可扩展性,不使用它的后果是牺牲应用程序的可扩展性。

于 2013-08-28T08:11:49.523 回答