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.


I think your implementation is very much MVP. If I were to classify it, I would be tending toward it being the Supervising Controller variant, regardless of the data binding mechanism that you reference. I say this as the Presenter's interaction with the View is very 'macro'. For me, the Passive View variant would have a lot more 'micro' interactions.

I generally find that if the view only has logic that's related to things that are specific to it, then that's acceptable. For example, a list of items might be represented in one view as a ListBox whilst in another view, that implements the same interface, the list might be represented as a ListView . Therefore, only the relevant view will know what SetState() means in each context. One of my 'Litmus Tests' for an MVP design is whether or not I could represent the view using a console. Regardless of whether this becomes reality, I find it helps to get the design and levels of abstraction just right.

Furthermore, logic in the view doesn't automatically reduce testability.

Another thing to always keep in mind with MVP design is testability. One of the key goals of the pattern is to support automated testing. If your design allows you to fully test the feature/use case's behaviour in an automated way with a fake view, then, IMHO, your design is good.

链接地址: http://www.djcxy.com/p/30236.html

上一篇: Powershell中命令* Nix'的等价物?

下一篇: 基于状态的MVP更新视图