2011-07-17 3 views
1

작은 응용 프로그램에서 작업하는 동안 코드 디자인 문제가 발생했습니다. (나는 초급반이다.)컨트롤러에 너무 많은 논리가 있고 서로를 호출하는 모델

특징의 측면에서 각각 2 석을 가진 테이블 목록이있다. 두 명의 플레이어가 같은 테이블에 앉으면 게임이 시작됩니다.

이 부분에서는 테이블 컨트롤러, 테이블 모델 및 게임 상태 모델이 있습니다 (게임 상태 만들기 란 게임이 시작되었음을 의미합니다).

사용자가 앉으면 테이블 컨트롤러에서 처리하는 ajax 요청을 실행합니다.이 요청은 테이블 모델에서 적절한 메소드를 호출하여 호출합니다. 테이블 모델이 양쪽 시트가 채워진 것을 발견하면 게임이 시작됩니다. 까다로운 부분입니다.

테이블 모델의 게임 상태 모델을 갖고 싶지 않습니다. 게임 상태 모델을 호출하는 것이 나중에 어려워 질 수 있습니다. 그래서 테이블 모델을 리턴하게 만들었습니다 : success => 테이블 컨트롤러에 true hash. 게임 상태 모델을 호출할지 여부를 결정합니다.

그러나 그렇다면 Rails 3 Way에 따르면 컨트롤러에 논리를 넣고 있음을 알 수 있습니다.

내가 경험할 수있는 것보다 더 경험이 많은 사람이 내가 더 잘할 수 있는지 말해 줄 수 있습니까?

"사용자가 부분 연결을 끊으면 게임을 포기합니다."라는 문제가 있습니다. 현재 사용자는 테이블 컨트롤러를 가져 와서 앱이 계속 연결된 상태임을 알 수 있습니다. 그리고 그 부분을 처리하는 게임이 결점을내는 것은 어색하고 결합하는 것처럼 보입니다.

또한 자바 스크립트 코드를 사용하여 각 유형의 리소스에 대해 하나의 setInterval을 가져 와서 모듈화 된 상태로 유지하려고합니다. 그러나 결과적으로 매 간격마다 6-7 개의 AJAX 요청을 생성합니다. 그리고 그것은 비효율적 인 것처럼 보입니다.

답변

3

좋습니다. 알겠습니다.

먼저 어떤 모델이 다른 모델인지 알고 있어야합니다. 우리의 경우, 우리는 아마 말할 수있는 뭔가 GameState

같은 -> 표 -> 사용자

모델이 그것의 오른쪽에있는 모든 것을 알고 있으며, 왼쪽으로 모델에 대해 아무것도 모르고 있다는 것을 의미한다. 이 방법을 사용하면 많은 논리가 자연스럽게 속하는 위치를보다 쉽게 ​​결정할 수 있습니다. 사용자 모델은 테이블 모델 자체에 대해 알지 못하기 때문에 테이블에 속한다는 것을 알기 때문입니다.

이제 게임에서 우리가 가진 여러 가지 "상태"에 대해 생각해 봅시다. 기다리고있는 테이블이

  • 게임 상태를 작성 및 하위 상태가 많이
  • 경기 후 점수가 계산됩니다, 변수는 업데이트됩니다이 과정을 할

    1. 사전 게임 상태

    # 1과 관련하여 이것이 우리가 처음 테이블에 속한 것으로 추측합니다. 그것은 자신과 자신이 속한 국가에 대해서만 알아야합니다. 그러나 그것은 단지 두 자리를 차지하고 채울 수있는 유일한 역할입니다. 게임이 언제 시작될 수 있는지에 대해서는 알 수 없습니다. 이것은 무엇을 의미 하는가? 게임 전 상태가 게임의 "상태"이기도하기 때문에 사실 GameState에 작업을 위임해야합니다. 게임 스테이트가 원한다면 "문지기"가 될 것이고 테이블은 단지 폰일 것입니다.그렇게 말하면 GameState 모델에서 Table 모델을 호출하여 게임을 시작할 수 있음을 확인하는 것이 좋습니다. 사용자가 테이블에 참여하기 위해 클릭하면 GameState 컨트롤러로 이동합니다 (로직이 모델에 속하는지 확인하여 컨트롤러가 모델의 메소드를 호출하는 것임). GameState 컨트롤러는이 사용자를 테이블에 추가하고 게임을 시작할 수 있는지 확인합니다 (모든 좌석이 채워지면 테이블 만 반환됩니다). 그렇다면 클라이언트에게 올바른 정보를 보내고 "Okay! Start!"라고 말합니다.

    일단 게임이 시작되면 GameState가 자신과 게임에 속한 데이터 (필요하면 테이블과 사용자)를 조작하는 것입니다. 게임이 끝나면 GameState는 멤버들과 함께 자신을 정리하고 DB에 자신을 저장합니다. 따라서 GameState처럼 모든 것이 전체 프로세스를 간과하는 것처럼 보이고 테이블/사용자는 GameState가 조작하는 데이터 일뿐입니다.

    사용자의 연결 해제와 관련하여 많은 상황없이 무엇이 옳은 일인지 말할 수 없습니다. 하지만 이런 식으로하면 폴링이 필요하지 않은 것처럼 보입니다. 내가 생각할 수있는 것은 사용자가 페이지를 탐색하거나 (브라우저를 닫거나 새 URL을 입력하거나 링크를 클릭하는 것) unload()을 사용하여 사용자가 왼쪽으로 있음을 알리는 요청을 서버에 보낼 수 있습니다. 또 다른 방법은 사용자가 서버에 보낸 또 다른 요청 인 "연결 끊기"를 클릭하는 것입니다.

    6-7 AJAX 요청을 보내야한다는 측면에서 모든 간격이 약간 과한 것처럼 보입니다. 정말로 원한다면 모든 리소스를 하나의 객체로 묶어서 간격마다 하나의 객체를 보내고 서버가 객체를 조작하게 한 다음 객체가 돌아 왔을 때 그것을 처리하도록해야합니다. 그러나이 모든 투표를 할 필요가없는 것처럼 보일 수도 있습니다. 필요한 경우 유효성 검사 및 암호화를 사용하여 GameState가 합법적 인 방법으로 전환되는지 확인해야합니다.

    행운을 빌어 요.

  • +0

    고마워요! 이것은 멋지게 보이며, 실제로 일을 정리합니다. 하나의 후속 질문. 나는 채팅 메시지, 좌석 상태 및 다른 사용자가 시작한 모든 것을 확인하기 위해 폴링 (폴링과 풀링을 이해하지 못함)을 사용합니다. (juggernaut 같은 것을 아직 사용하지 않았습니다.) 컴퓨터 충돌, 브라우저 충돌 및 기타 이상한 상황에서 사용자 존재를 제거하기 위해 last_checked_in 업데이트를 수행해야했습니다. 내가 잘못하고 있니? – Max

    +0

    채팅이있는 경우 폴링을 수행하는 유일한 방법은 setInterval을 사용하는 것입니다. [폴링] (http://en.wikipedia.org/wiki/Polling_ (computer_science))은 외부 소스 (데이터베이스)를 샘플링 할 때 사용됩니다. 컴퓨터/브라우저 충돌은 처리하기 어려운 문제입니다. Juggernaut는 응용 프로그램이 확장되면 확실히 갈 수있는 방법입니다. last_checked_in은 괜찮은 방법입니다. 15 초마다 사용자 입력이 필요하도록하는 게임 타이머가 있으면 응용 프로그램은 사용자가 실제로 있는지 여부를 감지 할 수 있습니다. 그래서 아니, 당신은 틀리지 않아. :) – vinceh

    관련 문제