我有一个系统(游戏),我尝试使用架构Model-View-Presenter实现。我现在所做的是演示者中的while循环,它连续调用视图方法进行显示。我这样做的方法是使用Producer / Consumer模式,其中View注册和触摸事件的事件处理程序(Android)并产生相应的触摸事件,即演示者在while循环中消耗。
现在我想在模型和演示者之间使用模式Observer / Suscriber。使用此Presenter将是Observer订阅模型状态的更改。问题是,演示者将根据视图中发生的事件执行模型中的更新。每次演示者在模型中执行一种方法时,它都会。可以改变其状态并通知演示者。我将在另一个线程中将每个更新的模型分开,但如果在while循环内的另一个线程中运行,我如何通知演示者?如果我调用方法通知观察者,当演示者将调用相应的方法?
它让我发疯了! :P我需要你的帮助队长!答案 0 :(得分:2)
你可能在架构方面过度设计了这个。 MVP和Producer / Consumer和Observable都在同一篇文章中。警钟响了。我怀疑你不需要生产者/消费者或观察者模式,MVP可能完全足够。
试试这个。
创建3个文件:
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是一个扩展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();