MVP 中的观察者模式

Observer Pattern in MVP

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

现在我想在模特和主持人之间使用模式 Observer/Suscriber。使用此 Presenter 将成为 Observer 订阅模型状态的更改。问题是,演示者将根据视图中发生的事件在模型中执行更新。每次演示者执行一个方法 in.the 模型时,它就会。可以更改其状态并通知演示者。然后我将在另一个线程中分离每个更新的模型,但是 如果这是 运行 在 while 循环内的不同线程中,我如何通知演示者?如果我调用notify observers的方法,presenter会在什么时候调用相应的方法?

快把我逼疯了! :P 我需要船长们的帮助!

没关系。您有一个对象 Presenter,它正在线程内的无限循环中使用。这并不意味着您不能在它被线程调用时调用它的方法。您唯一需要注意的是,如果线程 read/used 中的数据与观察者通知更改的相同,您应该同步它的访问。

所以,总而言之,虽然 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();

您可能在架构方面设计过度了。 MVP 和 Producer/Consumer 以及 Observable 都在同一个 post 中。警钟长鸣。我怀疑您不需要 producer/consumer 或观察者模式,MVP 可能完全足够了。

试试这个。

创建 3 个文件:

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

游戏主持人:

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()
    }
}

游戏视图

是一个接口

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

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

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

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

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

Fragment 控制任何与视图相关的内容(按钮、TextView 等)。它 通知 用户交互的演示者。

Presenter是引擎,它从View获取信息(在本例中是Fragment,但请注意这种模式很适合依赖注入?那是不是巧合。Presenter 不知道 View 是一个 Fragment——它不在乎)并将它与从 'below'(通信、数据库等)接收的信息结合起来,然后 命令相应的视图。

View 只是一个接口,Presenter 通过它与 View 进行通信。请注意,这些方法读作 commandsnot 读作 questions(例如 getViewState())和 notinform(例如 onPlayerPositionUpdated())- commands(例如 movePlayerHere(int position))。