Search code examples
javaandroidobserver-patternpresentation-model

Presentation Model for Android: how to wrap Model in Presentation Model?


I'm trying to make my app with PM design (MVC + Presentation Model), but I've already stuck on how to cleverly wrap Model classes in Presentation Model classes. Now, I write a simple code where a picture and a text are changed based on values in an instance of Model class.

// Disclaimer: 
// View and Controller are merged in this sample for clarity's sake. 

Enum

Enum AnimalSpecies {
    Dog, Cat, Rabbit, Bird,   
}

M of MVC + RM

class Model extends Observable {

    // in my actual code Model has 10+ member variables and most of them are Enum

    protected AnimalSpecies species;
    protected String name;
    protected Object update;

    public void setSpecies (AnimalSpecies species) {
        this.species = species;
        notifyUpdate(species); 
    }

    public void setName (String s) {
        this.name = s;
        notifyUpdate(name);
    } 

    public void notifyUpdate(Object o) {
        this.update = o;
        this.setChanged();
        this.notifyObservers(update);
    }
}

RM of MVC + RM

class PresentationModel extends Observable implements Observer {

@Override
    public void update(Observable model, Object data) {
        // Called when notified by Model

        // No idea what to write... but what I want to do is,  
        // a) determine what text for View to display
        // b) determine what pics for View to display, 
        // based on values of Model.    

        this.setChanged();
        this.notifyObservers(update);
    }    
}

VC of MVC + RM

class View extends Activity implements Observer {

    // This is View + Controller, so it'd implement some interfaces like onClickListener, 
    // and in events such as onClick(), values of Model class are changed, 
    // but for clarity's sake, I keep everything in onCreate() event. 

    TextView header;
    TextView footer
    ImageView imgview;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        header = (TextView) findViewById(R.id.header);
        footer = (TextView) findViewById(R.id.footer);
        imgview = (ImageView) findViewById(R.id.imgview);

        Model model = new Model();
        PresentationModel pm = new PresentationModel();
        model.addObserver(pm);
        pm.addObserver(this);

        model.setSpecies(AnimalSpecies.Cat);
        model.setName("Max");
    }

    @Override
    public void update(Observable pm, Object data) {

        // Called when notified by PresentationModel
        // *** varies based on parameters from PresentationModel

        header.setText(***);
        footer.setText(***);
        imgview.setImageResource(R.drawable.***);

    }

}

My question: how to write a logic in public void update() of class PresentationModel? I can get only an Object variable from NotifyObserver(), and even with nested switch or if ... else, I can't come up with codes at all...


Solution

  • Hmm, you probably want to tell your listeners what changed. For example, if the name field changed in the model, call notifyObservers(update, PROPERTY_NAME). Then the presentation model just needs logic to handle name changes.

    That said, I wouldn't recommend using Presentation Model without a framework. There's too much complexity and code required to fire events and move data around properly. Actually, even with a framework, there's a significant learning curve - but I do think it's a nice architecture for larger projects.

    JGoodies Binding is a good example of a Presentation Model framework. However, it's targeted at Swing applications. It can be adapted for Android with some effort, but I would look to see if a good Android-specific framework exists.