Java 接口如何从实现中删除依赖关系?

Java 接口如何从实现中删除依赖关系?,java,oop,interface,architecture,clean-architecture,Java,Oop,Interface,Architecture,Clean Architecture,我正在读鲍勃叔叔的《清洁建筑》一书。本书的一个要点是,您应该依赖于抽象,而不是实现 例如,他提到软件的高层不应该从底层知道任何东西(我同意)。他还指出,当高层需要与下层通信时,下层必须实现高层使用的接口。例如,如果用例层需要调用Presenter层,那么应该通过Presenter实现的接口OutputBoundary来完成,这样用例层就不依赖于Presenter。如果在没有界面的情况下这样做,那将非常糟糕,因为用例层取决于演示者层 这是怎么回事?如果将来Presenter层需要用例发送更多或不同

我正在读鲍勃叔叔的《清洁建筑》一书。本书的一个要点是,您应该依赖于抽象,而不是实现

例如,他提到软件的高层不应该从底层知道任何东西(我同意)。他还指出,当高层需要与下层通信时,下层必须实现高层使用的接口。例如,如果用例层需要调用Presenter层,那么应该通过Presenter实现的接口OutputBoundary来完成,这样用例层就不依赖于Presenter。如果在没有界面的情况下这样做,那将非常糟糕,因为用例层取决于演示者层

这是怎么回事?如果将来Presenter层需要用例发送更多或不同的数据,您不仅需要修改Presenter,还需要修改OutputBoundary接口和用例。因此,用例永远不会完全独立于演示者

如果演示者仅仅改变了方法的主体就改变了他显示数据的方式,那么用例层就不需要改变任何东西。如果演示者通过更改方法声明来更改其显示数据的方式,那么无论您是否拥有接口都无关紧要,因为您必须在用例层中修改方法调用。在这两种情况下,接口的使用都不重要

这里有我遗漏的东西吗?我知道一个界面的用途,我知道如果你有或计划有多个演示者,那么让他们实现一个通用的界面将是正确的做法,但即使如此,我也看不到他在书中提到的从较低层独立出来的独立性

这是怎么回事?如果将来演示者层需要更多或更多 用例要发送的不同数据,您不仅需要 修改演示者,但不修改OutputBoundary接口和使用 案例也是如此。因此,用例从来都不是完全独立的 来自演示者

如果presenter层需要更多或不同的数据,则用例层必须更改以提供该数据

但是,如果您决定在表示层中进行更改,或者用新技术替换它,但是信息是相同的,那么您将不需要修改用例层


与数据访问相同,您使用接口,因此它取决于应用程序,而不是相反,当您需要更改数据访问以使用不同的数据库技术时,只要您的数据访问层继续实现相同的接口,您不需要在应用程序中进行更改。

假设无线电是更高级别的软件,那么电池的依赖性将更低。在现实生活中,收音机并没有和Duracell电池紧密耦合,你们可以使用任何你们想要的电池

让我展示一个C#中的示例(抱歉,我没有安装Java编辑器,但代码非常简单):

使用方法:

IBattery battery = new Duracell();
var radio = new Radio(battery);
radio.TurnOn();
您的高电平-
收音机
不依赖于低电平
电池的实现

所以你可以使用任何你想要的电池

这是怎么回事?如果将来Presenter层需要用例发送更多或不同的数据,您不仅需要修改Presenter,还需要修改OutputBoundary接口和用例。因此,用例永远不会完全独立于演示者

答案是肯定和否定 是的,这是正确的,因为所有层都指向内部而不是外部 这使得层之间的通信基于接口/抽象。例如,应用层将针对接口实现所有代码,并且不知道该接口的实现,但由于较高层指向内部,因此它将消耗较低层的接口,然后实现它,从而使回答是

每一层本身都依赖于较低的一层,因此应用程序依赖于核心/实体 基础设施依赖于应用程序,但这里有一个技巧,在您的表示层中,您实际上将使用DI将每个接口的实现指向该接口,这将使它们仅在运行时相互依赖

在这张图中,你可以看到每一层的方向

如果演示者仅仅改变了方法的主体就改变了他显示数据的方式,那么用例层就不需要改变任何东西

是的,因为来自应用层的数据仍然相同,但是如果表示层需要完全不同,比如说视图模型,那么应用层将不得不更改数据,这可能需要更改持久性/基础结构层,这将导致更改应用层中的接口,而持久性/基础设施将需要实施

实际上,我建议你为贾森·泰勒观看这段视频

如果你有任何问题,请告诉我

IBattery battery = new Duracell();
var radio = new Radio(battery);
radio.TurnOn();