user
user

Reputation: 209

Good MVC design for calling a method by many classes

EDIT (16.05.2013):

I will use my third solution. Thanks everybody for help.

END OF EDIT (16.05.2013)

I have a View (inside a Controller) with an update method. The method has to be called by many classes. So I figured out two solutions:

  1. Make a field for the View/Controller in every class that needs to call the update method.
  2. Make the update method static.

What would be a better (M)VC design and what happens if two or more classes call the update method at the same time ?

Simplified Example 1:

public class View{
    public void update(){}
}

// Many classes:
public class AClass{
    private View view;

    private void aMethod(){
        view.update();
    }
}

Simplified Example 2:

public class View{
    public static void update(){}
}

// Many classes:
public class AClass{

    private void aMethod(){
        View.update();
    }
}

Edit (12.05.2013): I agree, that the "static solution" isn't good, especially for OOP.

I oversimplified a litte bit, so here is the actual design:

Let's say you have some MVC designed programs and want to put them together in a "big" program, but now the programs have to interact from time to time.

public class AView{
    public void update(){}
}

public class AModel{}

//Many of these:
public class AController{
    private AView aview;
    private AModel amodel;

    public AController(AView aview, AModel amodel){
        this.aview=aview;
        this.amodel=amodel;
    }
}

public class MainController{
    public MainController(){
        AView view1 = new AView();
        AModel model1 = new AModel();
        AController controller1 = new AController(view1, model1);

        AView view2 = new AView();
        AModel model2 = new AModel();
        AController controller2 = new AController(view2, model2);

        AView view3 = new AView();
        AModel model3 = new AModel();
        AController controller3 = new AController(view3, model3);
    }
}

Now let's say that controller1 and controller2 need to call the update method of view3. My current solution is to make a field of view3 in controller1 and controller2 (as you suggested).

AController controller1 = new AController(view1, view3, model1);
AController controller2 = new AController(view2, view3, model2);

Or should I refactor the whole design or create a "bridge" between the controllers ? How would that "bridge" then look like ?

End of edit (12.05.2013)

Edit (14.05.2013): I figured out a third solution: Every controller fires it's own events. For Example:

Controller1 and Controller2 fire events and Controller3 listens to them and then calls the update method of View3. What do you think about this solution ?

End of edit (14.05.2013)

Upvotes: 2

Views: 343

Answers (3)

user
user

Reputation: 209

I will use the following design, because it will be modular (Thanks @Hovercraft Full Of Eels for pointing out tight coupling):

public class MainController{

    private Controller1 controller1;
    private Controller2 controller2;
    private Controller3 controller3;

    public MainController(){
        controller1=new Controller1();            
        controller2=new Controller2();           
        controller3=new Controller3();

        addListeners();
    }

    private class Ctrl1Listener implements Controller1Listener(){        
        public void controller1ActionPerformed(Controller1Event e){
            //Calls the method of view3     
            controller3.update();
        }
    }

    private class Ctrl2Listener implements Controller2Listener(){           
        public void controller2ActionPerformed(Controller2Event e){
            //Calls the method of view3     
            controller3.update();
        }
    }

    private void addListeners(){
        controller1.addListener(new Ctrl1Listener());
        controller2.addListener(new Ctrl2Listener());
    }
}

Comments are highly appreciated.

Upvotes: 0

Hovercraft Full Of Eels
Hovercraft Full Of Eels

Reputation: 285405

Throw the static solution out, just don't even consider this, as by doing this you throw all OOP out the window. Give the Control a public update() method that calls the view's method if need be.

Having said this, your question though gives me concern regarding tight coupling.

These other classes that are needing to call the View's update -- are they part of the Control class/library? Only control should be calling update on the view.


Edit, you state:

Could you please explain more on "Static method throw all OOP out of window" I am eager to learn that.

When you make a method static it is no longer inheritable, and more importantly, it is no longer a method of an instance of a class, but rather a method of the object of the class. And so separate instances will no longer have their own unique method to call and it cannot obtain state data from the instance nor can it change the state of the instance.

Upvotes: 5

Kanagavelu Sugumar
Kanagavelu Sugumar

Reputation: 19260

I hope the entire model will update the same view and keep it updated for various datas.

public class View{
     private View(){}
     public void update(){}
     private static class singleTonFactory{
          private Static View obj = new View();
     }

     public static View getViewInstance (){
          return singleTonFactory.obj;
     }
}


 // Many classes:
public class AClass{
     private final View view = View.getViewInstance();

     private void aMethod(){
          view.update();
     }
 }

Upvotes: 0

Related Questions