이것은 어떤 패턴이며 어떻게해야합니까?


9

flash develop 및 flash cs5를 사용하여 as3에서 게임을 만들고 있습니다. 모든 것은 객체 지향입니다. 다른 클래스의 모든 인스턴스화에 대한 속성 참조가있는 하나의 "게이트웨이"클래스가 있는지 궁금하고이 게이트웨이 클래스를 새 객체에 전달하기 때문에 모든 클래스에 액세스 할 수 있습니다. 이렇게 :

 var block:Block = new Block(gateway);

 //In the block class:
 this.gateway.player.setHealth(100);
 //Or:
 this.gateway.input.lock();

이것은 싱글 톤 패턴이나 다른 것입니까? 내가해야합니까?

답변:


13

이를 컨텍스트 오브젝트 디자인 패턴 이라고 하며 싱글 톤 패턴보다 낫습니다.

  • 컨텍스트 객체는 테스트하려는 함수에 모의 컨텍스트를 전달할 수 있으므로 테스트에 도움이됩니다. 싱글 톤을 조롱하려면 싱글 톤이 아니라 싱글 톤을 만들어야합니다.
  • 컨텍스트 객체는 "전역 상태"를 명시 적으로 만들어 추론하기가 더 쉽습니다. 함수가 컨텍스트 객체를 사용하지 않으면 전역 컨텍스트 상태를 사용하지 않는 것입니다. 싱글 톤이나 전역 변수에 대해서는 그러한 보장이 없습니다.
  • 컨텍스트 객체는 사용하지 않으면 약간 느려집니다. 모든 함수 호출에 다른 매개 변수를 추가하기 때문입니다. 그것들을 사용하면 전역보다 빠를 수 있으며 거의 항상 싱글 톤보다 빠릅니다.
  • 컨텍스트 객체는 구현하기가 더 쉽습니다. 보통 그들은 정상적인 방법으로 더미 또는 스택에 산다. 싱글 톤은 많은 언어에서 스레딩과 관련된 까다로운 문제가 있습니다.

그래서, 이것은 싱글 톤이 아니며 싱글 톤보다 낫습니다.

그러나 여전히 많은 상태를 겪고 있습니다. 하나의 로컬 변수에 모두 유지한다는 사실은 더 명확하지만 여전히 우려의 혼란을 초래 합니다. 하나의 책임 규칙 을 명심 하십시오 . 플레이어와 현재 레벨을 소유 한 컨텍스트가 관련되어 있지만, 동일한 컨텍스트가 키보드 입력을 소유하는 이유는 무엇입니까?

예를 들어 다음과 같은 다양한 수준의 컨텍스트를 고려하십시오.

  • GameplayContext-플레이어, 적, 레벨 지오메트리 등을 소유합니다
  • InputContext-키보드 및 마우스 핸들, 입력 이벤트 등을 소유합니다.
  • GraphicsContext-텍스처, 창 핸들 등을 소유합니다.
  • GlobalContext-GameplayContext, GraphicsContext 및 InputContext를 소유합니다. 여기에서 서비스 로케이터 패턴 을 적용하여 필요에 따라 일부 컨텍스트를 다른 컨텍스트로 교체 할 수 있습니다. 또한 빠른 반복 및 테스트를 위해서는 실제 변수에 속해야합니다.이를 사용할 때마다 기술 부채가 발생 한다는 사실 만 인식하면됩니다 .

이러한 컨텍스트는 여전히 약간의 우려를 제기합니다. 일부 이벤트 핸들러는 GameplayContext를 사용하고 실제로 플레이어 만 필요합니다. 그러나 책임은 명확하게 정리되어 있습니다. GameplayContext를 사용하는 것은 텍스처를로드하지 않습니다. InputContext를 취하는 것은 플레이어를 죽일 수 없습니다.


+1 좋은 답변입니다. 속도 또는 스레딩 문제 중 일부는이 맥락에서 실제로 적용되지 않습니다 (ActionScript3는 스레딩을 지원하지 않으며 C ++에서 작동하는 많은 속도 개선 메커니즘은 AS3을 사용할 때 적용되지 않습니다).
bummzack

AS3VM에 대해서는 잘 모르지만 대부분의 동적 언어에서 로컬을 전달 / 수신 / 사용하는 비용은 여전히 ​​전역 조회 (해시 조회) 보다 훨씬 빠르며 (배열 조회) 그것을 얻기 위해 함수 (스크랩로드)를 호출합니다. 그래서 나는 여전히 조언이 적용된다고 생각합니다.

0

이것은 싱글 톤 패턴처럼 보이지 않습니다. 내가 이해하는 방식으로 중요한 게임 오브젝트에 대한 참조가있는 오브젝트를 모든 인스턴스에 전달합니다.

이것이 싱글 톤 패턴이면 다음과 같은 결과가 나타납니다.

AudioManager.getInstance().playSound(XY);

귀하의 경우에는 다음이있을 수 있습니다.

this.gateway.getAudioManager().playSound(XY);

기본적으로 동일하게 보이지만 실제로는 그렇지 않습니다. AudioManager과 같은 새로운 (확장 클래스) 로 바꾸려면 ExtendedAudioManagerSingleton 패턴을 사용하여 벽을 칠 것입니다. 게이트웨이 접근 방식은 잘 처리 할 수 ​​있습니다.

당신의 접근 방식의 단점은 gateway모든 곳 을 통과해야한다는 것 입니다. 서비스 로케이터 패턴 (에서 조 Wreschnig에 의해 제안 된 스레드), 당신의 "게이트웨이 패턴"에 대한 좋은 대체처럼 보인다.

때로는 과도하게 디자인하는 대신 간단하고 간단한 방법으로 실행하는 것이 좋습니다. 특히 작은 프로젝트 나 프로토 타입 일 때. 아마도 여러분은 gateway일종의 전역 변수를 만들 수있을 것입니다 . Game.gateway그것으로 실행합니다.


-2

싱글 톤 패턴을 포함하여이 문제에 대한 대부분의 솔루션에는 정적 변수를 사용합니다. 플레이어가 한 명 뿐인 경우 Player를 싱글 톤 클래스로 만들 수 있습니다. 즉 Player.currentPlayer와 같은 것을 통해 Player 인스턴스에 액세스 할 수 있습니다. 그러나 많은 사람들이 싱글 톤에 대해 분노합니다. 다양한 유용한 전역 또는 꽤 다항적인 전역 변수에 대한 정적 참조를 포함하는 ResourceManager 또는 유사한 클래스가있을 수도 있습니다. 코드에서 "Gateway 's"변수를 코드를 어디에나 전달하여 부 풀리는 대신 정적으로 액세스 가능하게 만들 수도 있습니다.


이 답변을 작성한 후 질문이 크게 바뀌어 편집 할 가치가없는 것처럼 보입니다.
Gregory Avery-Weir

2
제목 외에는 질문에서 변경된 것이 없습니다.
bummzack

1
뭐? 제목 외에는 변경된 것이 없습니다. -1
AttackingHobo

나는 여기서 제목을 생각하고 있다고 생각한다. 원본 제목이 "어떻게해야합니까?"와 같은 것을 기억합니다. 내가 대답했을 때 초기 제목 / 질문을 잘못 읽었을 가능성이 있습니다.
Gregory Avery-Weir
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.