为什么在Dao设计模式或其他设计模式中使用接口

问题描述 投票:23回答:6

请参阅以下Dao设计模式的组件:

数据访问对象模式或DAO模式用于将低级数据访问API或操作与高级业务服务分开。以下是数据访问对象模式的参与者。

数据访问对象接口 - 此接口定义要对模型对象执行的标准操作。

Data Access Object具体类 - 该类实现上面的接口。该类负责从数据源获取数据,该数据源可以是database / xml或任何其他存储机制。

模型对象或值对象 - 此对象是包含get / set方法的简单POJO,用于存储使用DAO类检索的数据。

当我们有一个具体的课程时,为什么我们需要一个INTERFACE?为什么我们不能直接使用它?这可能是一个天真的问题,但请帮助我明确这一点。不仅在DAO设计模式中,在其他设计模式中,使用INTERFACE也有点令人困惑。我同意这与代码可重用性和减少耦合有关。但任何人都可以请进一步解释。

java spring hibernate design-patterns
6个回答
23
投票

不仅在DAO设计模式中,在其他设计模式中,使用INTERFACE也有点令人困惑。

接口是Java中最常用的概念之一。让我用一个例子解释一下:假设你为汽车设计了一个GPS设备,它可以看到地图并自动将汽车转向地图中所示的方向。这种GPS设备可用于许多汽车,如奔驰,菲亚特等。对于每辆汽车,左右转动的机制可能根据汽车系统的实施而有所不同。因此,这些功能应该由汽车制造商编写,因此这些方法被放置在一个界面中,该界面由汽车制造商根据其汽车的实施来实现。该界面仅包括一组由汽车制造商定义的功能声明(在本例中)。得到它了?

要了解有关接口及其有用之处的更多信息,请阅读this article

我的问题是:当我们有一个具体的类时,为什么我们需要一个INTERFACE,为什么我们不能直接使用它。

在下面的答案中指出的许多其他好处中,您可以为实现DAO接口的不同数据结构(derby db,大堆栈等)创建许多DAO类。好处是,每个类都可以存储在DAO接口变量中,称为polymorphism


13
投票

实际上,当您只有一个实现时,没有必要拥有一个接口。但是在某种情况下,你对这个具体的课程没有依赖是非常实际的:

  • 测试调用DAO的服务:您可以编写一个模拟DAO,其行为与测试中所需的一样(例如,模拟没有数据库连接,很难自动重现)
  • 生成一些图层和你的DAO。您可以使用AOP围绕DAO方法生成缓存或事务处理。在这种情况下,您有一个实现DAO接口的对象,但与原始实现无关。
  • 切换数据库技术。如果从MySQL切换到DB2,您只需要编写接口的另一个实现并切换MySQL DAO和DB2 DAO

因此,为您提供DAO和服务接口是一个很好的做法。


7
投票

我的问题是,当我们有一个具体的课程时,为什么我们需要一个INTERFACE,为什么我们不能直接使用它。

这是简单的抽象。假设您使用Oracle数据库作为数据库。因此具体类将具有访问(CRUD操作)Oracle DB的逻辑。明天,如果您的许可证到期并且您不再想使用Oracle DB,那么您将需要使用MySQL。现在你必须重写已经提到的具体类,并且你必须重写服务层,因为通过直接使用具体类和它的方法,你在服务层和数据访问层之间有紧密耦合。人们应该始终考虑松散耦合的系统。

如果您使用接口而不是具体类,则服务层和数据访问层具有如何交互的契约。因此,服务层不会受到数据层更改的影响,因为合同没有改变,并且它们可以以相同的旧方式进行交互。


2
投票

将接口与实现分开始终是一个很好的设计。它为您的代码提供了更多的抽象和灵活性。 DAO接口的客户端不需要知道它是如何实现的,而只需要知道它提供的方法。

最后,接口是代码可维护性的良好实践。

只是补充一点,根据我通过模拟进行单元测试的经验,当你模拟的对象有一个接口时,创建模拟对象要容易得多。因此,对我而言,使用接口可以更容易地隔离和测试代码。


0
投票

这更多地围绕代码的逻辑分离。

有关接口的详细信息,请从Java阅读本页:

http://docs.oracle.com/javase/tutorial/java/concepts/interface.html


0
投票

一个很好的理由是它可以很容易地编写用于测试应用程序的模拟实现。

假设您要测试使用UserService的模块X.当您编写测试代码时,您将希望它不使用真正的UserService,而是使用UserService的特殊测试版本来返回一些预定义的测试数据。因此,在您的测试中,您将传递自己的IUserService模拟实现,而不是真正的UserService。

此外,它使将来使用IUserService的不同实现扩展系统变得更加容易。也许你现在有一个UserService,它从数据库中读取有关用户的信息。例如,将来您可能还希望拥有一个从LDAP获取信息的UserService。那只是IUserService的另一个实现。由于应用程序的其余部分仅通过接口使用UserService,因此可以轻松地将一个实现替换为另一个实现。

© www.soinside.com 2019 - 2024. All rights reserved.