【问题标题】:Presentation Model for Android: how to wrap Model in Presentation Model?Android 的演示模型:如何将模型包装在演示模型中?
【发布时间】:2012-08-14 05:15:43
【问题描述】:

我正在尝试使用 PM 设计(MVC + 演示模型)制作我的应用程序,但我已经坚持如何在演示模型类中巧妙地包装模型类。现在,我编写了一个简单的代码,其中根据 Model 类实例中的值更改图片和文本。

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

枚举

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

MVC 的 M + 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);
    }
}

MVC 的 RM + 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);
    }    
}

MVC的VC+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.***);

    }

}

我的问题:如何在PresentationModel 类的public void update() 中编写逻辑?我只能从NotifyObserver() 得到一个Object 变量,即使是嵌套的switchif ...else,我根本想不出代码...

【问题讨论】:

    标签: java android observer-pattern presentation-model


    【解决方案1】:

    正如 Peter 所指出的,如果没有框架,在 android 应用程序中应用 Presentation Model 模式将会有很多工作。 JGoodies Binding 是 Java Swing 的框架。我知道我迟到了。但是对于其他人或您未来的项目,您可能会感兴趣。我们的开源项目Robobinding 是一个用于Android 平台的数据绑定表示模型框架。当我们将MVC/MVVM/Presentation Model应用于android app时,我们真正想要的是有一个结构清晰的项目,更重要的是更容易进行单元测试。目前,在没有第三方框架的情况下,您通常会有很多代码(如 addXXListener()、findViewById()...),这些代码不会增加任何业务价值。更重要的是,您必须运行 android 单元测试而不是普通的 JUnit 测试,这需要很长时间才能运行并且使单元测试有些不切实际。由于这些原因,几年前我们开始使用RoboBinding。 RoboBinding 可帮助您编写更易于阅读、测试和维护的 UI 代码。 RoboBinding 消除了addXXListener 等不必要的代码 的需要,并将UI 逻辑转移到Presentation Model,这是一个pojo,可以通过普通JUnit 测试 进行测试。 RoboBinding 本身带有 300 多个 JUnit 测试以确保其质量。其他替代方案:Android-Binding、Bindroid 和 MvvmCross。

    【讨论】:

    • 如何将模型绑定到展示模型? RoboBinding 将表示模型绑定到视图 AFAIK。因此,对模型所做的更改会传播到表示模型。
    【解决方案2】:

    嗯,您可能想告诉您的听众发生了什么变化。例如,如果模型中的名称字段发生了变化,则调用notifyObservers(update, PROPERTY_NAME)。然后表示模型只需要处理名称更改的逻辑。

    也就是说,我不建议在没有框架的情况下使用 Presentation Model。触发事件和正确移动数据需要太多的复杂性和代码。实际上,即使有一个框架,也有很长的学习曲线——但我确实认为它对于大型项目来说是一个不错的架构。

    JGoodies Binding 是表示模型框架的一个很好的例子。但是,它针对的是 Swing 应用程序。它可以通过一些努力适应 Android,但我会看看是否存在一个好的 Android 特定框架。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-11-19
      • 1970-01-01
      • 2010-11-28
      • 2011-06-15
      相关资源
      最近更新 更多