MVP中的观察者模式

时间:2016-04-22 08:16:08

标签: java android model-view-controller observer-pattern

我有一个系统(游戏),我尝试使用架构Model-View-Presenter实现。我现在所做的是演示者中的while循环,它连续调用视图方法进行显示。我这样做的方法是使用Producer / Consumer模式,其中View注册和触摸事件的事件处理程序(Android)并产生相应的触摸事件,即演示者在while循环中消耗。

现在我想在模型和演示者之间使用模式Observer / Suscriber。使用此Presenter将是Observer订阅模型状态的更改。问题是,演示者将根据视图中发生的事件执行模型中的更新。每次演示者在模型中执行一种方法时,它都会。可以改变其状态并通知演示者。我将在另一个线程中将每个更新的模型分开,但如果在while循环内的另一个线程中运行,我如何通知演示者?如果我调用方法通知观察者,当演示者将调用相应的方法?

它让我发疯了! :P我需要你的帮助队长!

2 个答案:

答案 0 :(得分:2)

你可能在架构方面过度设计了这个。 MVP和Producer / Consumer和Observable都在同一篇文章中。警钟响了。我怀疑你不需要生产者/消费者或观察者模式,MVP可能完全足够。

试试这个。

创建3个文件:

  • GameFragment.java
  • GameView.java
  • GamePresenter.java

GamePresenter:

public class GamePresenter {
    private final GameView view;

    public GamePresenter(GameView view){
        this.view = view;
        NetworkController.addObserver(this);//listen for events coming from the other player for example. 
    }

    public void onSwipeRight(){
        // blah blah do some logic etc etc
        view.moveRight(100);
        NetworkController.userMovedRight();
    }

    public void onNetworkEvent(UserLeftGameEvent event){
        // blah blah do some logic etc etc
        view.stopGame()
    }
}

GameView

是一个界面

public interface GameView {
    void stopGame();
    void moveRight(int pixels);
}

GameFragment是一个扩展Fragment并实现GameView的类,并且有一个GamePresenter作为成员。

public class GameFragment extends Fragment implements GameView {
    private GamePresenter presenter;

    @Override
    public void onCreate(Bundle savedInstanceState){
        presenter = new GamePresenter(this);
    }
}

这种方法的关键是清楚地理解每个文件的作用。

片段控制任何与视图相关的内容(Buttons,TextView等)。它通知用户交互的演示者。

Presenter 是引擎,它从视图中获取信息(在这种情况下它是片段,但请注意这种模式很适合依赖注入?这不是巧合。演示者不知道View是一个片段 - 它并不关心)并将它与它从'下面'(通信,数据库等)接收的信息结合起来,然后命令相应地查看。

视图只是一个界面,Presenter通过该界面与View进行通信。请注意,方法读作命令作为问题(例如getViewState())和通知(例如onPlayerPositionUpdated()) - 命令(例如movePlayerHere(int position))。

答案 1 :(得分:1)

没关系。你有一个对象Presenter,它在一个线程内的无限循环中使用。这并不意味着你也不能在线程调用它时调用它的方法。您需要注意的唯一考虑因素是,如果线程读取/使用的数据与观察者通知相同,则您应该同步它的访问权限。

总而言之,当Presenter在无限循环内运行时,任何对它的调用方法都会立即得到解答(除非它们具有同步访问权限,在这种情况下它会阻塞直到它获得锁拥有权)

以下是完全正确的:

class Presenter implements IObserver
{
    public void aMethod() { }

    public void notifyObserver() { }
}

class Model
{
    private List<IObserver> observers = new ArrayList<>();

    public void addObserver(IObserver obs) { observers.add(obs); }

    public void notifyObservers()
    {
        for(IObserver o : observers) { o.notifyObserver(); }
    }
}


final Presenter myPresenter = new Presenter();
Model myModel = new Model();
myModel.add(myPresenter);

new Thread(new Runnable() 
{
    @Override
    public void run()
    {
        while(true)
        {
            myPresenter.aMethod();
        }           
    }
).start();