2014-04-15 4 views
2

저는 단일 책임 원칙 (SRP)을 염두에두고 GameManager를 만드는 것을 정당화 할 수 있을지 궁금합니다. 구체적인 예 : 메모리 게임의 GameManager (일치해야하는 카드 포함). 그것은 분명히 많은 책임이 있습니다 : 누가 턴을했는지 추적하고, 턴 사이를 전환하고, 게임이 끝난 시점을 추적하고, 승자가 누구인지를 추적합니다.단일 책임 GameManager 유형의 클래스에 대한 원칙

답변

2

중요한 것은 올바르게 작동하면 GameManager 수업에는 번으로 직접이 언급되어 있지 않습니다. 대신,이 책임을 다른 클래스에 위임 할 것이고, 이는 어떤 형태의 의존성 주입을 사용하여 전달 될 것입니다. 따라서 GameManager 클래스에는 하나의 책임이 있다고 말할 수 있습니다. 즉, 다른 클래스의 작업을 조정하는 것입니다. 변경해야 할 한 가지 이유가 있습니다. 게임 로직에서 새로운 클래스가 참여해야하거나 클래스 간의 상호 작용 순서를 변경해야하는 변경 사항을 수용해야합니다.

아주 간단한 예 (죄송합니다, C#을 구문,하지만 당신은 아이디어를 얻을) : 객체 responsabilities을 초과에 대한 의심

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

. 상당히 객관적인 SRP 개념 인 cohesion이 있습니다. Konamiman's answer에서 GameManager는 100 % 응집력이 있습니다. 모든 의존성 (인스턴스 필드)이 모든 public 메소드에서 사용된다는 것을 의미합니다.

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

당신이 당신의 객체 내부의 여러 응집력있는 구성 요소를 발견하면

class GameManager { 
    private int anInt; 
    private object aObj; 

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

:

0 %는 반대 것 Nice point @ Jackl56 : 속성 설정자와 게터에 관해서는 2 가지 옵션이 있습니다. 당신은 그것들을 고려할 수 없거나 그들이 당신의 응집을 낮추지 만 받아 들일만한 수준으로 생각할 수 있습니다.

+1

멋진 생각. 그러나 색상, 바퀴 수와 같은 속성이 다른 자동차는 어떻습니까? 클래스 멤버 변수의 하위 집합에서만 작동하는 속성 (get/set) 메서드가 있습니다. 또는 그것에 대해 다시 생각하면, 그것들은 의존성이 아닙니다. 그래서 여러분이 의존성을 말할 때 다른 클래스에 대한 참조 인 멤버 변수에 대해 이야기하고 있습니다. 이런 식으로 말하는 것이 맞습니까? –

관련 문제