繁体   English   中英

服务和DAO始终实现接口

[英]Service and DAO always implement interfaces

在我看到的所有MVC项目中,“服务”和“ DAO”类始终实现自己的接口。 但是几乎所有时候,我都没有看到过使用该接口的情况。

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

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>

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

有很多支持接口的论点,请参见Google。

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

  1. 想象一下,您将DAO实现从Hibernate更改为iBatis。 依赖接口而不是实现将对服务层有很大帮助。
  2. 如果您使用AOP或使用JDK动态代理的代理,则您的类必须实现接口。 CGLIB并非如此。
  3. 在服务层中,如果您希望将方法释放给其他客户端以进行调用,那么给它们“作为契约的接口”将比实现更有意义。
  4. 如果您要从daos.jar分离services.jar,则在daos上具有接口可以避免在daos.jar发生更改时重新编译services.jar。

简而言之,拥有接口就很好!

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

尽早使用接口可以使您的应用程序具有可伸缩性,并且不使用接口的后果就是牺牲了应用程序的可伸缩性。

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

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

在我看来,DI的最大优点不是 (通过简单地更改config XML中声明的类的类型)使实现的更改变得容易,而是使依赖关系的分离更加容易,从而使每个组件的分离测试更加容易。 。 您不需要一个孩子的接口。

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM