2014-04-15 53 views
2

我想知道如何有人證明創建一個GameManager,同時有單一職責原則(SRP)的想法。具體的例子:記憶遊戲的GameManager(帶你必須匹配的牌)。它顯然有很多責任:追蹤誰是輪到誰,輪流切換,追蹤比賽結束時間,獲勝者是誰以及更多...單類責任原則類型的類GameManager

回答

2

關鍵是如果你做得對,GameManager班級不會直接有你提到的所有責任。相反,它會將這些責任委託給其他類,這些類將通過使用某種形式的依賴注入來傳遞給它。所以你可以說GameManager類有一個單獨的職責:協調其他類的工作;並有一個單一的理由需要改變:適應需要新類參與的遊戲邏輯的變化,或者改變類之間交互的順序。

一個很簡單的例子(對不起,C#的語法,但你的想法):

public class GameManager 
{ 
    //constructor - note that the parameter types are interfaces, not classes 
    public GameManager(
     IPlayerManager playerManager, 
     ITurnManager turnManager) 
    { 
     this.playerManager = playerManager; 
     this.turnManager = turnManager; 
    } 

    public void DoNextTurn() 
    { 
     var nextPlayer = playerManager.GetNextPlayer(); 
     turnManager.ProcessTurn(nextPlayer); 
     //etc... 
    } 
} 
+0

我喜歡它。對於這種設計的後續問題:你總是會使用接口(IPlayerManager,ITurnManager),或者在某些情況下,你可能會說可以編程爲實現,因爲它不可能改變。換句話說,我在質疑抽象的必要性。 (否則我們可能會在整個程序的整個生命週期中將每個接口關係的一個類整個生命週期,這似乎是多餘的) –

+0

@ Jackl56您的代碼總是依賴實現,而不是具體的類。否則,你將會得到緊密耦合的代碼,這些代碼是不可測試的。看看這裏:http://williamdurand.fr/2013/07/30/from-stupid-to-solid-code – Konamiman

+0

我已閱讀該鏈接。很有用。所以我明白,它不會像測試那麼容易,但將可測試性留在一邊,對具體類進行編程有什麼問題?我同意這會使這些類之間緊密耦合,但是那裏有什麼錯誤? (除了可測試性) –

3

當約超過對象responsabilities疑問。有一個與SRP相關的概念,cohesion,這是相當客觀的。在Konamiman's answer中,GameManager具有100%的內聚力。這意味着所有的依賴項(實例字段)都用於所有公共方法。

0%是相反的:

class GameManager { 
    private int anInt; 
    private object aObj; 

    public void Foo() { 
     // Do anything but using anInt or aObj 
    } 
} 

如果你發現你的對象裏面幾個凝聚力的成分:

class GameManager { 
    private T1 obj1; 
    private T2 obj2; 

    public void Foo() { 
     T1.F1(); 
    } 

    public void Goo() { 
     T2.G1(); 
    } 
} 

類應該一分爲二:

class GameManagerFoo { 
    private T1 obj1; 

    public void Foo() { 
     T1.F1(); 
    } 
} 
class GameManagerGoo { 

    public void Goo() { 
     T2.G1(); 
    } 
} 

尼斯點@ Jackl56:關於屬性設置者和獲得者你有2個選項。你不能考慮他們,或者你可以考慮他們降低凝聚力,但達到可以接受的水平。

+1

好主意。但是,具有不同屬性(例如顏色和車輪數量)的汽車又如何呢?那麼我會擁有隻對類成員變量的子集進行操作的屬性(get/set)方法。或再次思考,這些不是依賴關係。所以當你說依賴關係時,你所說的成員變量是對其他類的引用。這樣說是否正確? –