【问题标题】:Why use interfaces为什么要使用接口
【发布时间】:2018-10-04 09:36:07
【问题描述】:

我看到了接口的好处,能够通过合约添加新的实现。

我没有看到以下问题: 想象一下,您有带有方法“startTransaction”的接口 DB。 一切都很好,你在 MySQL、PostgreSQL 中实现它。但是明天你转移到 mongodb - 那么你就没有事务支持了。

你是做什么的? 1)空方法 - 不好,因为你认为你有交易但你没有 2) 创建你自己的 - 然后你应该有一些与常规“startTransaction”方法不同的参数。

除此之外,有时简单的界面根本不起作用。 示例:您需要针对不同实现的附加参数。

【问题讨论】:

  • 这称为接口隔离原则。如果您不仅有跨国数据库,则应将transnational 方法移至子接口interface trasactionalDB extends DB。具有事务的数据库应该从trasactionalDB 继承,而不是直接从DB 继承。
  • 有什么意义,我不能在 Mongo 中使用事务。如果它对我没有任何帮助,为什么还要使用接口隔离原则?
  • Mongo 将直接实现DB 接口,无需与事务相关的方法。
  • 我的 MongoDB 版本不支持事务。
  • 正如我在回答中试图指出的那样,拆分接口,这样您就不必实现事务功能。 IE。 ITransactable 接口可以强制执行事务功能,而不是其他任何东西。这样,就不要为您的 mongo-db 使用 ITransactable

标签: interface


【解决方案1】:

如果您在界面上公开事务的概念,那么无论如何您必须在功能上支持事务,因为界面的用户在逻辑上会依赖它。即,如果调用者可以启动事务,那么他们希望也能够回滚多个查询的事务。由于 Mongo 本身没有任何回滚事务的概念,因此存在以下两种可能性之一:

  1. 您可以在代码中实现回滚查询的可能性,模拟本机不支持它的数据库的事务功能。 (这在 Mongo 中是否可靠是一个值得商榷的话题。)
  2. 您的界面在错误的抽象级别上工作。如果您的接口承诺了实现无法提供的功能,那么无论是接口还是实现都是不现实的。

在实践中,Mongo 和 SQL 数据库是如此不同的野兽,如果不改变大部分业务逻辑,您将永远不会做出这种改变;或者您仅使用极少的公分母接口来指定您的接口,当然不会在抽象接口上公开特定于技术的概念。

【讨论】:

  • 是的,正确的。我是说接口并不总能提供你想要的:)
  • 这取决于“你想要什么”。您当然可以定义一个涵盖 Mongo 和 SQL 数据库的接口,但它必须类似于 storeData(data); getData(id);即极少的东西。如果您正在尝试制作一个涵盖汽车和摩托车的界面,它可能必须只是interface Vehicle,而不是interface FourWheeler。问题在于你如何使用它的细节,而不是接口的概念。
  • 我想要交易,如果我提供 storeData 我将有参数来提供交易支持。所以问题仍然存在,无论是在“startTransaction”还是 storeData(data, transactionFlag)
  • 您无法使用承诺事务的接口来实际覆盖非事务性数据库。 那是你的问题。
  • 那么在这种情况下如何解决这个问题?
【解决方案2】:

您大部分是正确的,接口可能非常有用,但在(快速)更改代码时也存在问题,关于接口的最佳实践是使它们尽可能小。

当某物可以处理事务时,创建一个仅用于处理事务的接口。将它们分成逻辑上尽可能小的部分,这样,当新类出现时,您可以为它们分配可以确定其方法的特定接口。

对于多参数问题,这确实是有问题的,看看能不能确定这个具体的值是否可以移到构造函数中,或者表明你正在做的动作确实和不做的动作有明显区别需要这个参数。

希望对你有帮助,祝你好运

【讨论】:

  • 是的,使用接口时我没有看到任何好处。如果我有 5 个不同的支付提供商,它们都有不同的参数和逻辑,而且问题更大。
  • 我不同意这一点,每个支付提供商都有接口会很有帮助,这样你的方法可以简单地强制一个类型是接受的支付提供商之一。这样,你就不用关心你使用的是什么数据库,你只关心功能。这就是接口的有用之处
  • 嗯,在现实世界中,支付提供商不会就所有事情达成一致——这只是在书本上。实际上,一个适用于某些支付代码,另一个适用于其他东西。
  • 没错,现实总是比书本复杂:)。但是您(我猜)有一些触发付款的方法,知道该项目/类/某物支持的接口类型有助于确定要执行的正确操作,例如(静态)switch 语句
【解决方案3】:

您是对的,接口用于通过合同添加新的实现,但这些实现必须具有一些相似性。 举个例子: 你不能使用人机界面来实现狗,因为狗是一个活的有机体。 您在这里尝试做的同样的事情。您正在尝试使用 sql db 实现来实现非 sql db。

【讨论】:

  • 我认为这并不完全正确,您可以发送消息以从非 sql 数据库和 sql 数据库中检索相同的值,这取决于接口中定义的内容。但在大多数情况下,是的,您谈论的是根本不同的事情
  • 所以你在说代码中的任何地方我都应该用 if 语句检查数据库是否支持事务?那也不好
猜你喜欢
  • 2015-04-11
  • 1970-01-01
  • 2016-12-29
  • 2020-05-14
  • 1970-01-01
  • 2010-10-11
  • 2012-01-21
  • 1970-01-01
  • 2010-10-01
相关资源
最近更新 更多