如何解决循环包装的依赖性


11

我正在重构一个大型代码库,其中大多数类位于一个包中。为了获得更好的模块化,我为每种功能都创建了子包。

我记得在某处学习过包依赖关系图不应包含循环的信息,但我不知道如何解决以下问题:Figure在package中figureLayout在package中layoutLayout需要该图执行布局,因此package layout依赖于package figure。但另一方面,a Figure可以Figure在其内部包含其他s,它们具有自己的Layout,这使得package figure依赖于package layout

我有一些解决方案,例如创建一个实现并将其放入包中的Container接口。这是一个好的解决方案吗?还有其他可能性吗?FigureLayout

谢谢


它是模块(例如不同的Jars)不能具有循环依赖关系。包可以并且经常具有循环依赖关系,只要它们属于同一模块即可。
lorus

@lorus这不是设计问题吗?
vainolo

2
不它不是。包通常只是一个命名空间。只有当它们用于其他用途时,它才能更改,例如,更改其在OSGi环境中的内容可见性。否则不要打扰。
lorus

1
请注意,许多权威机构都谴责周期性依赖关系,有时是有充分理由的,但是在盲目重构之前,您应确保这些原因之一实际上适用于您。如果包结构没有给您带来麻烦,并且您出于良心无法理解为什么将来会这么做,那么就不要为了满足抽象的体系结构价值而改变如此根本的东西。
Kilian Foth,

Answers:


9

您应该考虑控制反转

您基本上为自己定义了一个接口,该接口Layout位于您自己的包中的Layout类附近,因此您将拥有一个实现包和一个公共接口包-例如,将其称为Layoutable(我不知道这是否是正确的英语)。现在-版面不会实现该接口,而是Figure类。同样,您将为Figure创建一个接口Drawable,例如。

所以

my.public.package.Layoutable
my.implementation.package.Layout
my.public.package.Drawable
my.implementation.package.Figure

现在-Figure实现Layoutable,因此可以由Layout使用,(我不确定是否是您想要的)-Layout实现Drawable,可以在Figure中绘制。关键是,公开某些服务的类可通过接口(在这里为Layout和Layoutable)使它可用-想要使用该服务的类必须实现该接口。

然后,您将拥有类似将创建者对象绑定在一起的东西。所以,创作者将有依赖关系Layout以及对Figure,但LayoutFigure自己是独立的。

那是个粗略的主意。

Kirk Knoernschild 撰写的《Java应用程序体系结构》一书是解决此问题的极佳方法。


Container与问题中建议的界面不同吗?
vaughandroid

是的-不会-我不会像我所说的那样将它们放在同一包装中。而且背后没有太多理论。而且在这种情况下,仅在一侧完成是不够的,您必须在两侧都进行。好的?
michael_s

糟糕,我错过了原始问题中有关Container与装在同一包装中的问题Layout。那将行不通,而您的解决方案将行得通。
vaughandroid

嗯-好的-尽管我被黑客入侵时,我似乎已经错过了Container的一部分-应该将其命名为Container;)
michael_s 2013年

0

我不太清楚a Figure是什么,但是也许应该和a放在同一个包中Layout

您提出的Container接口解决方案不起作用-除非将Container接口放在第3个程序包中,否则这两个程序包之间仍然存在循环依赖关系。请参阅michael_s的答案以解决问题。

正如其他人所提到的,另一件事-可能永远不会成为问题。你只是如果碰到问题,未来Figure,并Layout希望在单独的模块。如果有必要,可以在需要时进行处理,但是鉴于这两个类似乎密切相关,因此这似乎不太可能。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.