XNA에서 Game1을 정적으로 만드는 것은 나쁜 생각입니까?


10

Game1클래스를 정적으로 사용 하는 것은 정말 나쁜 생각 입니까? 현재 Game1수업 시간에 TileHandler현재 타일 세트와 관련된 모든 것을 AnimalHandler처리하고 모든 동물을 (놀랍게도) 처리 하는 클래스가 있습니다 .

이제 내가 AnimalHandler타일을 걸을 수 있는지 확인하고 TileHandler문제가 발생하거나 걸을 수있는 타일 목록을 전달 AnimalHandler해야합니다.

더 쉬운 것은 Game1정적 인 상태 로 만드는 AnimalHandlerGame1._tileHandler.WalkableTile(position)입니다.

이제 나는 이것이나 어떤 문제를 일으키는 것으로 즉시 잘못된 것을 볼 수 없지만 정적 클래스를 사용하기 시작했을뿐입니다.

답변:


9

이제 나는 이것이나 어떤 문제를 일으키는 것으로 즉시 잘못된 것을 볼 수 없지만 정적 클래스를 사용하기 시작했을뿐입니다.

반짝이는 새 망치가 있으면 모든 문제가 못처럼 보입니다.

일반적으로 정적 인스턴스 및 / 또는 메소드가 올바르게 사용되면 (인스턴스 별 상태가 없거나 의존하지 않는 것 ) 아무 문제가 없습니다 . 그러나 귀하의 경우 인스턴스별로 종속성 을 숨기고 오용 하여 종속성 제거와 혼동합니다. 또한 Game1클래스 의 구현 세부 사항을 노출하는 것으로 보이며 일반적으로 나쁩니다.

다음은 문제의 요점입니다.

... 내가 AnimalHandler타일을 걸어서 이동할 수 있는지 확인하고 싶다면 TileHandler문제가 발생하거나 걸을 수있는 타일 목록을에 전달 AnimalHandler해야합니다.

AnimalHandler이 타일 을 필요로하는 자체가 나쁜 디자인 일 수 있다는 가능성을 무시하면 (선택한 이름 으로이 클래스의 세부 사항을 말하기가 어렵습니다) ... AnimalHandler걸을 수있는 타일 목록이 필요한 경우 다음 목록이 필요합니다 걷기 쉬운 타일. 일반적으로 코드를보다 자체 문서화 하기 때문에 종속성을 덜 명시 적으로 만드는 것이 좋습니다. 에 직접 목록을 전달하면 해당 목록 AnimalHandler이 필요하다는 사실을 명시 적으로 알 수 있습니다. 대신 코드의 다른 곳에있는 정적 목록에 액세스 할 수 있도록 모든 것을 정적이고 공개적으로 만들면 실제로 해결하거나 제거하지 않고 종속성을 숨기면 됩니다.

규모를 조정할 필요가없는 작은 게임의 경우, 그 자체로는 문제가되지 않지만 나쁜 습관의 길을 따라갈 수 있으므로 그렇게하지 않는 것이 좋습니다. 최소한 다음에 작업 할 프로젝트에서이 점을 명심하십시오.


아멘! 당신은 내가 실제로 대답하지 않은 좋은 점을 만집니다.
Nate

+1 의존성을 숨기고 글로벌 상태를 도입하는 것이 실제로 문제입니다
ashes999

4

정적 컨텍스트에서 TileHandler를 호출하는 것이 최상의 디자인이 아닌 이유는 디자인의 구성 요소를 분리 할 수있는 분리하기 때문입니다.

앞으로 둘 이상의 TileHandler를 사용하기로 선택한 경우이 변경을 수용하기 위해 많은 작업을 수행해야합니다.

TileHandler를 제거하도록 선택하면이 변경 사항을 수용하기 위해 많은 작업을 수행해야합니다.

나중에 현재 TileHandler와 다른 방식으로 타일을 처리하는 다른 레벨 / 영역을 빌드한다고 가정하십시오. 그런 다음 사용할 타일 처리 방법을 지정하거나 다른 핸들러를 호출해야합니다.

TileHandler가이를 사용하는 객체에 매개 변수로 전달 된 경우 다음에 다른 것을 전달하거나 나중에이를 사용하는 객체에 다른 타일 핸들러를 설정할 수 있습니다.

개인적으로 정적 컨텍스트에서 XNA 게임의 많은 것들에 액세스하고 그 중 두 개 이상을 가질 수 없다고 가정합니다.

다음 게임에서 게임 엔진 코드를 재사용하려면 현재 정적으로 작성했던 많은 것들을 다시 작성해야 할 것입니다.

한마디로 :

정적 컨텍스트를 사용하지 않는 것을 선호합니다.

개체를 가능한 한 매개 변수로 전달하면 게임 요소가 분리되어 현재 또는 미래의 프로젝트에보다 쉽게 ​​수정 / 재사용 할 수 있습니다. 또한 대량의 코드의 복잡성을 조금 더 쉽게 관리 할 수 ​​있습니다 (대규모 게임에서 게임 클래스에 수백 명의 정적 관리자가 있다고 생각).

정적 컨텍스트에 찬성하여 :

정적 컨텍스트에서 객체를 선언하고 액세스하면 수백 명의 정적 관리자가 필요없는 작은 게임을보다 쉽게 ​​작성할 수 있습니다. 정적으로 액세스되는 하나 이상의 추가 매개 변수가 필요하지 않으므로 많은 메소드와 생성자를 단순화합니다.


2

나는 그것이 단순한 게임에 대한 매우 나쁜 생각이라고 생각하지 않지만 http://www.nuclex.org/articles/4-architecture/6-game-components-and-game-services 를 볼 수도 있습니다. 대화 형 게임 구성 요소를 구축하는 방법에 대한 더 나은 아이디어


단순한 게임이 아니라면 어떤 문제에 대해 생각할 수 있습니까?
Harold

코드 가독성, 테스트 가능성 및 우수한 아키텍처 관행은이를 피하는 것이 좋습니다.
smnbss

2

TileHandler 및 AnimalHandler와 같은 것 게임 화면의 수준을 높입니다. 타이틀 화면에 TileHandler에 대한 액세스 권한이 필요하며 게임을 처음로드 할 때 초기화됩니까? 아마 아닙니다.

XNA State Management 샘플을 확인하십시오 . 여기에는 많은 코드가 있지만 기본 게임은 기본적으로 게임 상태 (또는 화면) 스택을 초기화합니다. 각 화면은 다른 화면과 상당히 독립적이며 게임 자체의 단순화 된 버전으로 실행됩니다. PlayScreen에는 정적 멤버가있을 수 있으므로 PlayScreen 구성 요소에 액세스 할 수 있습니다.

기본 게임에서는 몇 가지 스태틱을 사용하지만 InputHelper, Log 또는 Config 판독기와 같은 매우 낮은 수준입니다. 모든 게임에서 기본적으로 제공되므로 기본 엔진을 빠르고 쉽게 이식 할 수 있습니다. 화면은 실제 게임 로직이 발생하는 곳입니다. 그래서 긴 대답은 짧습니다. 아니, 이론상 나쁜 생각은 아니라고 생각하십시오. 정적으로 만드는 것을 조심하십시오. 일단 무언가를 정적으로 만들고 나면 마음이 바뀌면 엄청난 일이됩니다.


0

여기에 제기 된 요점은 모두 좋습니다. 내 경험 (게임보다 비즈니스 응용 프로그램에 더 많은 가중치가 있음)에는 정적 클래스와 멤버가 많이 사용되며 여러 번 사용했습니다. 요구 사항과 복잡성이 증가함에 따라 정적 클래스를 재활용하고 인스턴스 클래스로 변환하고 전달하기 시작했습니다.

내가 정하고 싶은 점은 정적 클래스를 사용하면 게임을 꺼내는 데 도움 되지만 계속 진행해야하지만 여전히 올바른 일을 수행한다는 것입니다. 인터페이스 또는 기본 클래스를 구현하여 쉽게 찢어 변환 할 나중에 인스턴스 클래스에.

예방의 온스는 치료의 가치가있다, 그래서 당신의 정체되는 클래스가 당신을 묶어 묶기 힘들게 만들지 않도록하십시오. 인터페이스를 구현하는 정적 클래스를 사용하여 메소드를 리팩터링하는 것은 매우 쉬우므로 새 인터페이스 매개 변수를 승인하고 정적 클래스 참조 대신 해당 인터페이스를 사용합니다.


0

예, 일반적으로 항상 나쁜 생각입니다.

변경 데이터가 포함 된 객체 (예 : 읽기 전용 상수 및 조회 테이블 제외)를 정적 클래스로 바꾸는 것은 좋은 디자인이 다이빙을하는 곳입니다.

  1. 모듈성을 없애고 코드 재사용을 방해하는 우연한 의존성을 촉진합니다. 게임용 편집기를 작성하고 싶다고 가정하자. 갑자기 Game1공유 라이브러리로 쉽게 이동할 수없는 클래스가 많이있을 것이다 .

  2. 코드를 테스트 할 수 없게됩니다. 단위 테스트는 종속성을 모의하거나 시뮬레이션하여 (가능한 한 최소한으로 유지해야 함) 나머지 클래스와 개별 클래스를 분리하여 작동합니다. 정적 클래스는 언제든지 액세스 할 수 있고 여러 테스트를 통해 상태를 전달하거나 테스트를 완료하기 전에 초기화해야 할 수 있으므로 책임이 있습니다.

  3. 의존성을 숨 깁니다. 서비스 제공 업체 안티 패턴 (XNA, Game.Services에서도 사용)과 마찬가지로 클래스는 외부에서 볼 수없는 종속성을 선택할 수 있습니다.

이 접근 방식은 정적 클래스와화물 열차 호출 ( Game.Instance.ActorManager.Enemies.FindInRange(10)기차와 같은 체인 기호로 인해 소위 유사)을 결합하면 구성 요소가 갑자기 Game클래스를 필요로 할 뿐만 아니라 Instance무언가를 반환 하는 정적 속성을 갖는 클래스 ActorManager이 특성 EnemiesA의 객체를 반환 재산 FindInRange()방법을.

변경 가능한 정적 클래스를 작성하는 데 동의하는 유일한 변명은 여전히 ​​배우고 있으며 여전히 좋은 디자인과 나쁜 선택을 발견 할 수있는 훈련 된 눈을 꾸준히 적용 할 수 없다는 것입니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.