Question

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

Was it helpful?

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.

OTHER TIPS

As Peter pointed out, without a framework, there will be a lot of work to apply Presentation Model pattern in android app. JGoodies Binding is the framework for Java Swing. I know i am late for the reply. But for others or your future projects, you may be interested. Our open source project Robobinding is a data-binding Presentation Model framework for the Android platform. When we apply MVC/MVVM/Presentation Model to android app, what we really want is to have a clear structured project and more importantly easier for unit tests. At the moment, without an third party framework, you usually have lots of code(like addXXListener(), findViewById()...), which does not add any business value. What's more, you have to run android unit tests instead of normal JUnit tests, which take ages to run and make unit tests somewhat impractical. For these reasons, some years ago we started RoboBinding. RoboBinding helps you write UI code that is easier to read, test and maintain. RoboBinding removes the need of unneccessary code like addXXListener or so, and shifts UI logic to Presentation Model, which is a pojo and can be tested via normal JUnit tests. RoboBinding itself comes with more than 300 JUnit tests to ensure its quality. Other alternatives: Android-Binding, Bindroid and MvvmCross.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top