views:

1114

answers:

3

Hello!

I am trying to implement some sort of MVC in Java. Actually it's more of a MVP but this doesn't really matter to my problem.

Following situation: I've got a GUI, made with Netbeans (because of the better GUIeditor) which is updated and changed frequently.

As my main project is easier to maintain in Eclipse I chose to import the Netbeans project into Eclipse as a separate project. So here I am with a project "App" containing the controller and the model package and a project "GUI" containing the view package. The problem is that the pattern I am following along has a cyclic dependecy between the view and the controller. Whenever the view changes, the controller gets notified decides which data to get from the model and then makes the changes to the view.

When I add App to the build path of GUI and the other way round, I will end up with this error message "A cycle was detected in the build path of project 'GUI'". I mean that's true, this cycle is already in my design.

Currently at startup I register a view to its controller in the following way (this is no real code, I am trying to shorten it)

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)    
   }
   ...
}

So you see the connection is made by passing a reference to the controller and then registering a listener onto this view. The problem is: if I don't have the GUI project in App's buildpath the import can't be resolved, same happens for not having App in GUI's build path.

I'd like to keep this project structure and also stick to my MVC architecture. How can I work around it? What are your suggestions?

+2  A: 

First of all, you may want to use interfaces rather than actual classes to represent the controller and view to each other.

That sort of problem is fairly common, and unfortunately, I don't think there's really a good solution because projects shouldn't create a cycle in Eclipse (are they allowed to in Netbeans? I find that surprising).

The most you could do is develop each other independently, and use a common project with the shared interfaces that each part of the system would depend on. That can at work in some designs. You can then have another driver project that knows both parts and does the actual initialization.

If you really want to avoid that, you may need to use a dependency injection like Spring.

Uri
+6  A: 

You have your listeners backwards from the usual way - normally, the controller has the initiative. It creates the view object and registers itself as a listener for view events.

Additionally, the listener type should be an interface defined in the View project. Then, the Contoller implements that interface and the view does not have to know about the concrete controller classes. Cycle resolved. You can do this in your "reverse" setup too, of course.

Michael Borgwardt
A: 

Circular dependencies between classes is not a problem per se (its a feature). However, you should check your design and justify the depenedencies.

Eclipse projects are perhaps a bit overused. Unfortunately, Eclipse doesn't really handle having many (10+ or so ) projects, and the othervise excellent partial compiler gets slower and the compiling process seems to get more buggy.

In several development projects i've been involved in, merging and reducing the number of projects has led to shorter build times and less build problems.

In inhouse applications, large and small, and if it is likely that everyone working on the code will have access to all the code, then there is actually little point in dividing the code between projects.

If you are worried about keeping track of the dependencies, it is possible to enforce rules for dependencies between packages.

Its quite common to have a "business layer" project, a "data" layer project and a gui project for each "module" in a large application, and then you are bound to end up with a few circular dependencies if you are not creating artifical "interface projects" etc.

Before you go to a great length to remove dependecies, consider if the dependcies in fact are real and the projects maybe should be merged instead.

Remember that abstract concepts like "modules" or "layers" does not neccesarily mean that you have to have matching projects or folders (or whatever.) Eclipse projects are a groups of files that you work on, nothing more or less really.

You might want to read about the-mythical-business-layer.

KarlP