我正在尝试用Java实现某种MVC。实际上它更像是一个MVP,但这对我的问题并不重要。
以下情况: 我有一个用Netbeans制作的GUI(因为GUIeditor更好),它经常更新和更改。
由于我的主项目在Eclipse中更易于维护,因此我选择将Netbeans项目作为单独的项目导入Eclipse。所以这里我的项目“App
”包含控制器和模型包以及包含视图包的项目“GUI
”。
问题是我遵循的模式在视图和控制器之间具有循环依赖性。每当视图发生更改时,控制器都会收到通知,决定从模型中获取哪些数据,然后对视图进行更改。
当我将App
添加到GUI
的构建路径而反过来时,我将最终收到此错误消息“在项目'GUI'的构建路径中检测到一个循环” 。 我的意思是,这个循环已经在我的设计中了。
目前在启动时我通过以下方式向其控制器注册视图(这不是真正的代码,我试图缩短它)
package view;
import controller.*;
class viewA{
...
public viewA() {
controllerA.register(this);
}
...
}
package controller;
import view.*;
class controllerA implements SomeListener{
...
protected viewA[] registeredViews;
public static register(viewA interestedView){
arrayPush(registeredViews,interestedView);
interestedView.addSomeListener(this)
}
...
}
因此,您可以通过将引用传递给控制器,然后将侦听器注册到此视图来进行连接。问题是:如果我在GUI
的构建路径中没有App
项目,则无法解析导入,在App
中没有GUI
也是如此的构建路径。
我想保留这个项目结构,并坚持我的MVC架构。我该如何解决这个问题?你有什么建议吗?
答案 0 :(得分:7)
你的听众会以通常的方式倒退 - 通常,控制者都有主动权。它创建视图对象并将其自身注册为视图事件的侦听器。
此外,侦听器类型应该是View项目中定义的接口。然后,Contoller实现该接口,视图不必知道具体的控制器类。周期已解决。当然,您也可以在“反向”设置中执行此操作。
答案 1 :(得分:4)
类之间的循环依赖关系本身并不是问题(它的一个特性)。 但是,您应该检查您的设计并证明依赖性。
Eclipse项目可能有点过度使用。遗憾的是,Eclipse并没有真正处理许多(10个以上)项目,而另一个优秀的部分编译器变慢,编译过程似乎变得越来越多。
在我参与的几个开发项目中,合并和减少项目数量可以缩短构建时间并减少构建问题。
在内部应用程序中,无论大小,如果很可能每个处理代码的人都可以访问所有代码,那么在项目之间划分代码实际上没什么意义。
如果您担心跟踪依赖关系,可以强制执行包之间的依赖关系规则。
在一个大型应用程序中为每个“模块”创建一个“业务层”项目,一个“数据”层项目和一个gui项目是很常见的,然后你最终会遇到一些循环依赖项。不是在创造人为的“界面项目”等。
在您花费很长时间去除依赖性之前,请考虑事实上的依赖性是否真实,以及项目是否应该合并。
请记住,像“模块”或“图层”这样的抽象概念并不一定意味着你必须拥有匹配的项目或文件夹(或其他任何东西。)Eclipse项目是你工作的一组文件,没有或多或少真的
您可能想了解the-mythical-business-layer。
答案 2 :(得分:2)
首先,您可能希望使用接口而不是实际类来表示控制器并相互查看。
这类问题相当常见,不幸的是,我认为没有一个很好的解决方案,因为项目不应该在Eclipse中创建一个循环(他们是否允许在Netbeans中使用?我觉得这很令人惊讶)。
您可以做的最多是独立开发,并使用共享接口的共同项目,系统的每个部分都依赖于该共享接口。这可以在一些设计中起作用。然后,您可以拥有另一个知道这两个部分的驱动程序项目并进行实际初始化。
如果你真的想避免这种情况,你可能需要像Spring一样使用依赖注入。
答案 3 :(得分:1)
您也可以将两个项目之一的.jar文件添加到另一个项目中,而不是将其依赖于项目本身。请记住在必要时更新jar。