Etkinlik Zamanlayıcı için tekil kalıptan nasıl kaçınılır?


13

Oyunum için bir Etkinlik zamanlayıcı yapmak istiyorum, temel olarak bir Oyun Etkinliğinin tetiklenmesini planlamak istiyorum. Bu bir kerelik bir tetikleyici veya periyodik bir tetikleyici olabilir (5 saniye temelinde "E_BIG_EXPLOSION" tetikleme olayı ...).

Bunun bir Singleton kullanmak için iyi bir yer olabileceğini düşünmek cazip gelebilir, ancak singletonlar oldukça kötü olabilir ve bir hastalık gibi yayılma eğilimindedirler ... bu yüzden onlardan kaçınmaya çalışırım.

Bu durumda singleton kullanımından kaçınmak için hangi tasarımı önerirsiniz?


Singleton alternatiflerine bu cevaba bakınız
BlueRaja - Danny Pflughoeft

Yanıtlar:


12

İletileri iletmesine veya almasına izin verilen çok iyi tanımlanmış bir arabirim kümesine sahip olmalısınız - onlara bir EventScheduler'a bir başvuru vermek önemsiz olmalıdır. Değilse veya olay planlayıcısını "çok fazla" farklı türe geçirmeyi gerektiriyorsa, ellerinizde daha büyük bir tasarım sorununuz olabilir (tek tektonların çözme değil, şiddetli bir bağımlılık) ).

Zamanlayıcıyı ihtiyacı olan arayüzlere geçirme tekniğinin bir " bağımlılık enjeksiyonu " biçimi olmasına rağmen, bu durumda yeni bir bağımlılık enjekte etmediğinizi unutmayın . Bu, sistemde zaten var olan bir bağımlılıktır, ancak şimdi bunu açık bir hale getiriyorsunuz (bir singletonun örtülü bağımlılığına karşı). Genel bir kural olarak, açık bağımlılıklar daha fazla kendi kendini belgelediklerinden daha fazla tercih edilir.

Ayrıca, etkinlik planlamasının tüketicilerini birbirinden ayırarak kendinize daha fazla esneklik sağlayabilirsiniz (hepsi aynı zamanlayıcıya bağlı olmaları gerekmediğinden), bu da yerel istemci / sunucu kurulumlarını veya bir dizi başka seçeneği test etmek veya simüle etmek için yararlı olabilir - bu diğer seçeneklere ihtiyacınız olmayabilir, ancak kendinizi bunlardan yapay olarak kısıtlamak için çaba sarf etmediniz, bu bir artı.

DÜZENLEME: Demek istediğim zamanlayıcıyı dolaşmaktan bahsettiğim şey şudur: çarpışmaya yanıt vermekten sorumlu bir oyun bileşeniniz varsa, muhtemelen fizik katmanınızın bir parçası olan bazı çarpışma cevaplayıcı fabrikası aracılığıyla yaratılır. Fabrikayı bir zamanlayıcı örneği ile oluşturursanız, bu örneği oluşturduğu yanıtlayıcılara iletebilir ve bu da olayları yükseltmek (veya belki de diğer olaylara abone olmak) için kullanabilir.

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

Bu açıkça nesne modelinin ne olduğunu bilmediğim için çok şık ve basitleştirilmiş bir örnek; bununla birlikte, olay zamanlayıcısına bağımlılığın açık hale getirildiğini gösterir ve daha fazla kapsülleme için bir miktar potansiyel gösterir (yanıtlayıcıları, Zamanlayıcı aracılığıyla olayları yükseltmek için somun ve cıvatalarla uğraşan fabrika.Bu, her bir bireysel yanıtlayıcı uygulamasını, sisteminiz için ideal olabilecek çarpışmada hangi özel olayın yükseltileceği gibi olay sevk sisteminin uygulama detaylarından izole edecektir. - ya da değil).


Cevabınız için teşekkürler, bağımlılık enjeksiyonunu düşündüm. Çözümünüzü biraz daha iyi belirleyebilmeniz çok güzel olur mu? (Sahte Kod? Diyagramı?). Sanırım fikrini takip ediyorum, ama belki de bu sadece benim kendi konsept yorumum.
Bay

Bunu, hangi sınıflarınızın programlayıcıya olay gönderip aldığını bilmeden yararlı bir şekilde yapmak zordur.


7

Bir olay dağıtıcısı, singleton'un dünyanın en kötü fikri olmadığı durumlardan biridir , ancak bundan kaçınmaya çalıştığınız için sizi alkışlıyorum. Burada bazı fikirler bulabilirsiniz .


1
Teşekkürler !, her singleton bir Kitten
Öldürüldüğünde

3

Singletonlardan da kaçınma eğilimindeyim ama singletons olarak en anlamlı birkaç nesne var ve merkezi mesajlaşma sistemi bunlardan biri. Duyduğum rantlara rağmen, singletonlar kesinlikle küresel değişkenlerden / fonksiyonlardan çok daha iyi çünkü her zaman kasıtlı olarak ele almalısınız (küresel değerlere karşı sadece sihirli bir şekilde ince havadan ortaya çıkıyor).

Sonunda her mesaj gönderen ve alıcı olması gerekir bazı kesişim ortak noktası ve mesajınızın gönderenlerin her direkt mesaj alıcıları hakkında bilmek zorunda ziyade her şey tarafından paylaşılan ortak singleton'ununu alarak ayrılmış Nesnelerinizi tutmak için çok daha iyidir.

Etkinlik sisteminiz için başka bir mimarinin tasarlanabileceğinden emin olmama rağmen, bana göre özellikle düşünmek için bir çaba kaybı gibi görünüyor, özellikle bir etkinlik sistemi kullanırken zaten kullanmamanız için büyük bir kazanç.

DÜZENLEME: Belirli bir tetikleyiciye gönderilen patlama olayına ilişkin özel örneğinize gelince, olayların büyük olasılıkla merkezi olay sisteminde değil başka bir nesnede (kule silahı veya bu patlamalara neden olan herhangi bir şey) gönderilmesini isterim. Ancak o olayların hala sevk edilecektir için merkezi olay sistemine.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.