2010-08-14 66 views
2

因此,我打算使用模型視圖演示者(「被動」模式,其中UI非常笨,並將所有事件發送給演示者,演示者負責處理模型)來粘合我的域的業務邏輯和用戶界面。演示者在MVP中的實現問題

我的問題是我的Presenter應該如何。這是我想要的嗎?

public class TicTacToeGamePresenter 
{ 
    private readonly ITicTacToeView view; 
    private readonly PlayerController model; 

    public TicTacToeGamePresenter(ITicTacToeView view) { 
     this.view = view; 
    } 

    ... 
} 

我應該通過構造函數注入傳遞預期的ITicTacToeView的實例嗎?這將允許我使用這個TicTacToeGamePresenter類與Forms,WPF,WebForms等。我只需要確保我的View實現了ITicTacToeView接口。

或者我應該只是實例化我打算直接使用的具體類的種類,只是有一個無參數的構造函數?這似乎有點毫無意義,但我不得不問:(

我目前擁有的ITicTacToeView接口定義爲:

public interface ITicTacToePassiveView 
{ 
    event EventHandler<EventArgs<Point>> ButtonClicked; 
    void PlayerOPlayed(Point location); 
    void PlayerXPlayed(Point location); 
    void EnableStartButton(); 
    void DisableStartButton(); 
} 

還有一兩件事。當我的編碼結束了的TicTacToeGamePresenter構造。這個:

public TicTacToeGamePresenter(ITicTacToePassiveView view) 
{ 
    this.view = view; 

    IGameLogicAnaliser gameLogicAnaliser = new GameLogicAnaliser(); 
    IPlayer playerO = new Player(gameLogicAnaliser); 
    IPlayer playerX = new Player(gameLogicAnaliser); 

    Game game = new Game(playerO, playerX); 

    this.playerOModel = new PlayerController(playerO, game); 
    this.playerXModel = new PlayerController(playerX, game); 
} 

現在,在看了代碼後,我認爲,也許最好是通過給上面的類提供這個'類依賴關係更明確「類實例的責任:

public TicTacToeGamePresenter(ITicTacToePassiveView view, IPlayer playerO, IPlayer playerX, Game game, PlayerController playerOModel, PlayerController playerXModel) 
    { 
     this.view = view; 
     this.playerO = playerO; 
     this.playerX = playerX; 
     this.game = game; 
     this.playerOModel = playerOModel; 
     this.playerXModel = playerXModel; 
    } 

哪一個會更好? 謝謝

回答

1

我會去你的第一個選擇:使用構造函數將視圖注入演示者,因爲它將允許您支持不同類型的UI,前提是它們都實現了界面。

另外,從單元測試的角度來看,你的生活會更簡單,因爲實現該接口的任何模擬類可用於您的測試

編輯:從WCSF是怎麼做的新增代碼示例 WCSF使用依賴注入並且每個視圖都有一個注入視圖的主持人的屬性。這同樣適用,並且不需要構造函數方法,但是這需要暴露一個公共View屬性。

[CreateNew] 
public DefaultViewPresenter Presenter 
{ 
    set 
    { 
     this._presenter = value; 
     this._presenter.View = this; 
    } 
} 
1

我不認爲你有很多選擇,但使用構造函數(或參數)注入。

在運行時,您的視圖將在其演示者首次實例化時實例化;如果您在演示者中創建視圖,那麼您將使用視圖的單獨實例,並且您將不會處理任何事件。


如果您使用的是IoC container創建您的演講,我贊成第二種方法來構造函數。如果你不是,那麼你要求你的視圖代表演示者實例化IPlayers,PlayerControllers和Games,並且它可能不應該知道如何做到這一點。 Take a look here關於您爲什麼要使用IoC容器的一些討論。

+0

我最終會開始使用IoC容器。但現在我已經有很多我必須學習的東西,並且自己造成了足夠的破壞。 – 2010-08-14 14:34:56

+0

順便說一句,你鏈接的帖子看起來不錯。 – 2010-08-14 14:39:54

+0

還有一個問題,你說:「在運行時,當演示者首次實例化時,你的視圖已經被實例化;如果你在演示者中創建視圖,那麼你將使用視圖的單獨實例,而沒有你期望的事件將被處理。「我不能只是在Presenter中實例化視圖嗎?這樣View只會在Presenter之後被實例化。或者我錯過了什麼? – 2010-08-14 16:25:17