mardi 5 avril 2016

MVP update view based on state

I'm trying to implement the MVP pattern, or my own interpretation/variant of it. I'm curious to know if what I'm doing is acceptable as an MVP pattern.

Say for instance that I have 3 buttons and 4 labels. Each button also maps to a state. So for instance, button1 maps to state1, button2 maps to state2, and button3 maps to state3. Each button click changes the state of my app which is held in a State Manager class. The State Manager class uses the observer pattern to notify observers that the state has changed.

In my view, I grab the user input, in this case the button click, and then immediately pass the event to the presenter. So I may have something like this.

button1.addActionListener(new ActionListener()
{
  public void actionPerformed(ActionEvent e)
  {
    presenter.btn1Pressed();
  }
});

Then I might have a method in the presenter like the following:

public void btn1Pressed(){
    stateManager.setState(state1);
}

Now the state manager class changes its state and notifies its observers. So in my Presenter class I have:

@Override
public void stateChange(State state){
    switch(state){
    case state1:
        view.state1(); //view is an interface not a concrete.
        break;
    }
}

Then in my view class I have the state1 method:

@Override
public void state1(){
    button1.setEnabled(false);
    button2.setEnabled(false);
    button3.setEnabled(true);
    label1.setVisible(true);
    label2.setVisible(false);
    label3.setVisible(true);
    label4.setVisible(false);
}

All of the methods are different. For example state2 might be:

@Override
public void state2(){
    button1.setEnabled(true);
    button2.setEnabled(false);
    button3.setEnabled(true);
    label1.setVisible(false);
    label2.setVisible(false);
    label3.setVisible(true);
    label4.setVisible(false);
}

Therefore, the view has knowledge of how to render itself, so I wouldn't consider this a Passive View implementation. It also really isn't Supervising Controller either as it doesn't bind to a model. It obviously does have some presentation logic. I tried to completely remove it and make it a passive view but it didn't feel natural. For example when I tried to make it a passive view I did the following:

In my presenter class

private void state1(){
    view.setButton1Enabled(false);
    view.setButton2Enabled(false);
    //...
}

In the view

public void setButton1Enabled(boolean enabled){
    button1.setEnabled(enabled);
}
public void setButton2Enabled(boolean enabled){
    button2.setEnabled(enabled);
}
//...

However, that requires a lot of methods to handle this. I also tried a presentation model pattern, but I felt that only mucked it up even more.

I prefer my implementation although it keeps a bit of presentation logic in my view. Would my implementation still lend itself to MVP? I realize that patterns are to be interpreted but I'm curious to know if leaving small amounts of presentation logic in my view is okay.

Aucun commentaire:

Enregistrer un commentaire