이벤트 스케줄러의 싱글 톤 패턴을 피하는 방법은 무엇입니까?


13

내 게임의 이벤트 스케줄러를 만들고 싶습니다. 기본적으로 게임 이벤트 트리거를 예약 할 수 있기를 원합니다. 이것은 일회성 트리거 또는 주기적 트리거 (5 초마다 트리거 이벤트 "E_BIG_EXPLOSION"...) 일 수 있습니다.

이것이 싱글 톤을 사용하기에 좋은 장소라고 생각하고 싶지만 싱글 톤은 매우 악할 수 있으며 질병처럼 퍼지는 경향이 있습니다. 그래서 나는 그들을 피하려고 노력합니다.

이 경우 싱글 톤 사용을 피하기 위해 어떤 설계를 제안 하시겠습니까?


참조 이 답변 싱글을 번갈아에
대니 Pflughoeft - BlueRaja

답변:


12

메시지를 전송하거나 수신 할 수있는 매우 잘 정의 된 인터페이스 세트가 있어야합니다. EventScheduler에 대한 참조를 제공하는 것은 쉽지 않습니다. 그렇지 않은 경우 또는 이벤트 스케줄러를 "너무 많은"고유 한 유형으로 전달하는 것과 관련이 있다고 생각되면 손에 더 큰 설계 문제 (단독이 악화되는 경향이있는 무차별 종속성)가있을 수 있습니다. ).

스케줄러를 필요로하는 인터페이스로 스케줄러를 전달하는 기술은 " 종속성 주입 "의 한 형태 이지만이 경우에는 새로운 종속성을 주입하지 않습니다 . 이것은 시스템에 이미 가지고있는 종속성이지만, 이제는 명시적인 것으로 만듭니다 (단일 톤의 암시 적 종속성과 비교). 일반적으로 명시 적 종속성은 자체 문서화가 많을수록 바람직합니다.

또한 이벤트 예약 소비자를 서로 동일한 스케줄러에 연결하지 않아도되므로 이벤트 소비자를 서로 분리하여 유연성을 높일 수 있습니다. 로컬 클라이언트 / 서버 설정 또는 기타 여러 옵션을 테스트하거나 시뮬레이션하는 데 유용 할 수 있습니다. -다른 옵션이 필요하지 않을 수도 있지만 인위적으로 자신을 제한하려는 노력을 기울이지 않았습니다.

편집 : 스케줄러를 전달할 때 말하는 것은 이것입니다. 충돌에 반응하는 게임 구성 요소가 있으면 물리 계층의 일부인 충돌 응답기 팩토리를 통해 생성 될 수 있습니다. 스케줄러 인스턴스를 사용하여 팩토리를 구성하면 해당 인스턴스를 작성하는 응답자에게 전달한 다음이를 사용하여 이벤트를 발생 시키거나 다른 이벤트를 구독 할 수 있습니다.

class CollisionResponderFactory {
  public CollisionResponderFactory (EventScheduler scheduler) {
     this.scheduler = scheduler;
  }

  CollisionResponder CreateResponder() {
    return new CollisionResponder(scheduler);
  }

  EventScheduler scheduler;
}

class CollisionResponder {
  public CollisionResponder (EventScheduler scheduler) {
    this.scheduler = scheduler;
  }

  public void OnCollision(GameObject a, GameObject b) {
    if(a.IsBullet) {
      scheduler.RaiseEvent(E_BIG_EXPLOSION);
    }
  }

  EventScheduler scheduler;
}

게임 오브젝트 모델이 무엇인지 알 수 없기 때문에 이것은 분명히 끔찍하게 고 안되고 단순화 된 예입니다. 그러나 이벤트 스케줄러에 대한 종속성을 명시 적으로 설명하고 추가 캡슐화 가능성을 보여줍니다 (스케줄러와 동일한 개념 레벨에서 상위 레벨 충돌 응답 시스템과 통신하는 경우 응답자에게 스케줄러를 전달할 필요는 없음). 스케줄러를 통해 이벤트 발생의 기본 요소를 처리하는 팩토리 이것은 충돌시 발생할 특정 이벤트와 같이 이벤트 디스패치 시스템의 구현 세부 사항에서 각 개별 응답기 구현을 분리합니다. -아닙니다).


귀하의 답변에 감사드립니다, 나는 의존성 주입에 대해 생각했습니다. 솔루션을 조금 더 잘 지정할 수 있다면 매우 좋을까요? (의사 코드? 다이어그램?). 나는 당신의 생각을 따른다고 생각하지만, 그것은 아마도 그 개념에 대한 내 자신의 해석 일뿐입니다.
Mr.Gando

어떤 클래스가 스케줄러에 이벤트를 보내고 받는지 알지 못하면 유용한 방식으로 수행하기가 어렵습니다.

내 엔진에서 모든 게임 엔티티는 "이벤트 디스패처"컴포넌트를 첨부 할 수 있습니다.
Mr.Gando

7

이벤트 디스패처는 싱글 톤이 세계에서 최악의 아이디어 가 아닌 경우 중 하나 이지만 피하려고 노력한 것에 대해 박수를 보냅니다. 당신은 여기에 몇 가지 아이디어를 찾을 수 있습니다 .


1
고맙습니다!, 싱글 톤이 만들어 질 때마다 새끼 고양이
죽습니다

3

싱글 톤도 피하는 경향이 있지만 싱글 톤으로 가장 적합한 몇 가지 개체가 있으며 중앙 메시징 시스템이 그 중 하나입니다. 내가 들었던 욕설에도 불구하고, 싱글 톤은 전역 변수 / 함수보다 확실히 낫습니다. 왜냐하면 항상 고의적으로 문제를 해결해야하기 때문입니다 (전세계의 가치와는 달리 얇은 공기에서 마술처럼 나타납니다).

결국 모든 메시지의 송신자와 수신자가 있어야합니다 일부 교차로의 공통점을, 그리고 당신의 메시지를 보낸 사람의 각 직접 메시지 수신기에 대해 알고있는 것이 아니라 모두가 공유하는 공통의 싱글을함으로써 분리 된 개체를 유지하는 것이 훨씬 낫다.

이벤트 시스템을 위해 다른 아키텍처가 고안 될 수 있다고 확신하지만, 특히 이벤트 시스템을 사용하는 것이 이미 사용하지 않는 것보다 큰 승리를 거두는 경우 너무 많이 생각하는 것은 낭비입니다.

편집 : 주기적 트리거로 발송 된 폭발 사건의 특정 예에 관해서는 아마도 중앙 사건 시스템이 아닌 다른 물체 (예 : 포탑 총 또는 폭발을 일으키는 원인)로 사건을 발송했을 것입니다. 그러나 이러한 이벤트는 여전히 중앙 이벤트 시스템 으로 전달 됩니다 .

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