It depends ...
The main goal of MVP is to separate complex decision logic from UI code in such a way that both become easier to understand and to maintain. Often another goal is to make the decision logic in the presenter testable.
The MVP pattern was described by Fowler in 2004 and he retired it in 2006 by splitting the pattern into Supervising Conroller (SC) and Passive View (PV). In SC, the View is bound to the Model but not in PV; in PV, the View is only changed by the Presenter directly.
In both SC and PV, the Presenter has to update the View and react to changes the user made to the View, such as entering text or pressing a button. When you let the View call methods on the Presenter, then the problem you describe arises because the View needs a reference to the Presenter and vice versa. If you do this, you simply can make a decision who starts it all up. Options are:
- The View creates an instance of the Presenter. When the View is loaded, it passes itself to the Presenter in an initialize function on the Presenter.
- The other way around: Presenter creates View and passes itself to the View in an initialize function on the View.
- You introduce a third object that creates both View and Presenter, wires them together and initializes them both.
All options allow you to reach "MVP goals" of separation of concerns and increased testability of decision logic. I don't think any of these methods is theoretically right or wrong –you just have to pick the one that is most appropriate to the technology you use. And it's best to be consistent in your choice throughout the application.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…