2012-09-19 15 views
9

Ben bir web dev (oyun hobi olarak) ve kendimi birkaç kez aşağıdaki paradigmayı kullanıyorum. (Her ikisi de sunucu mimarisi geliştirirken ve video oyunu dev çalışmaları ile.) Gerçekten çirkin görünüyor, ama etrafta bir çalışma bilmiyorum. Oyun devresine bir örnek vereceğim, çünkü yakın zamanda bunu fark ettim. Bu üzerinde çalıştığım bir RPG. Her savaş başlatıldığında, CombatEngine iki savaşçı partisini yaratır. Her Muharip açık bir komut almayan oyuncular için hamle dikte sorumlu olan verilen Muharip, ilişkilendirilen bir ArtificialIntelligence nesnesi kurar: BuradaSınıf inşasında geçen garip referanslar

public class Combatant { 

    ArtificialIntelligence ai = null; 

    public Combatant() 
    { 
     // Set other fields here. 

     this.ai = new ArtificialIntelligence(this); 
    } 

} 

Sevmiyorum şu şekildedir: İç saha (ArtificialIntelligence) inşaat sırasında bir Combatant alır, çünkü uygun eylemleri dikte etmek için bazı Combatant alanlarına ihtiyaç duyar. Bu nedenle, kolaylık sağlamak için, ArtificialIntelligence nesnesine arg olarak iletilen savaşçıya bir referans yapıyorum, ancak bu nesne ai nesnesinin kendisine bir referans içeriyor! Bu garip özyinelemeyi yaratıyor, ama etrafta nasıl çalışacağımı bilmiyorum. AI nesnesi, muhariplere özgü alanların iyi bir şekilde ele alınmasını gerektiriyor, bu yüzden de tüm nesneye geçtim, ancak nesnenin daha sonra üstlerindeki muhatapta yer alan ai alanının referansını nasıl içerdiğini sevmiyorum üstteki ai sınıfında bulunan alan. Bu kötü bir uygulama mı yoksa sadece düşünmeyi mi düşündüm? Burada "tasarım" sorunu olmamasına rağmen

+6

Yığınlama hatası mı alıyorsunuz? Bundan şüphe duyuyorum, ve değilse de, burada referans olarak geçen bir tekrarlama yok. Bence burada bir sorun değil. –

+1

Woops, ticaret tarafından bir matematikçiyim, bu yüzden bazı terminolojilerim eksik. Haklısın, bu sadece referans geçiyor. Bu hala bir sorun değil mi? Bu formda referanslar yerleştirmek kötü bir uygulama değil mi? Ve sorunuzu cevaplamak için, herhangi bir hata almıyorum. Sadece kötü göründüğünü ve fikir almak istediğini düşündüm. – Sal

cevap

9

- bu sadece geçiyoruz referans var - önemli bir hususu da diğer sınıfa this geçirmeden Alanlarınızda önce tüm başlatmak gerektiğidir. Aksi halde, diğer sınıf, muhtemelen tutarsız bir durumda this'a erişebilir. Bu bazen kurucudan this "kaçış" ı bırakmayı denir. Bunu yapma

...

public class BadCombatant { 

    ArtificialIntelligence ai = null; 
    String someField; 

    public BadCombatant() { 
     this.ai = new ArtificialIntelligence(this); 
     // Don't do this - ArtificialIntelligence constructor saw someField as null 
     someField = "something"; 
    } 
+1

+1 Bazı IDE'ler kurucularda “bunu sızdırmak” konusunda uyarır. –

+1

Açıkçası, “ArtificialIntelligence” ın * yapıcısı * (ve çağırdığı herhangi bir yöntem), "someField" öğesini "null" olarak görecektir. –

+1

Bu döngüsel bağımlılığı korumanın iyi bir fikir olduğunu sanmıyorum. Cevabımı görün! Bu bağımlılığın iki sınıfa veya tamamen yeni bir sınıfa taşınabilmesi için iki sınıfa kısmen bağımlı olmalarına gerek yoktur. – CKing

4

Kesinlikle halkalı bağımlılığı önleyeceğini. İçinde kurtarma için tek sorumluluk ilkesi geliyor. Combattant'ta bir Yapay Zekaya referans gösterme ihtiyacını ortadan kaldırabilirsiniz. ArtificialIntelligence yerine ArtificialIntelligence'a bağlı olan tüm kodları Combatant'tan taşıyın. CombatEngine aşağıdakiler gerçekleşir:

  1. Artificialntelligence ile ilgisi yoktur Bağımsız Muharip örneğini oluşturun.

  2. Uygun yapay zenginlik örneğini oluşturun ve daha önce oluşturulmuş Savaşçıyı geçin.

Alternatif olarak, Combattant ve ArtificialIntelligence geçirilen CombatController adlı yeni bir sınıf oluşturabilirsiniz. CombatEngine aşağıdakileri: başka bir sınıf üzerinde hiçbir bağımlılık ile Artificialntelligence oluşturun başka sınıfa

  • hiçbir bağımlılıkları ile

    1. Oluştur Savaşçı

    2. bir CombatController oluşturun ve geçmek Combatant ve ArtificialIntelligence nesnelerinin kullanılması. CombatController, Savaşçıyı kontrol etmek ve AI davranışını ele almak için yöntemleri ortaya çıkarmalıdır.

    Yukarıdaki yaklaşımdan hangisini kullandığınızdan bağımsız olarak, sizi rahatsız eden döngüsel bağımlılığı ortadan kaldırırsınız.

    Bu yanıtı cep telefonumdan alıyorum ve biçimlendirmenin bir ağrı oluşturduğundan bir kod örneği veremediğim için üzgünüm.

  • +0

    +1 Elbette daha fazla seçenek var; Örneğin, ComuntantState adlı Yapay Sinirlik'in yeni bir sınıfa ihtiyacı olduğu Combatant'tan alan çıkartabilirsiniz. CombatantState, Combatant'ta bir alan olacaktır ve ArtificialIntelligence, CombatantState'i kabul edebilir. En iyi çözüm, kodunuzun ihtiyacına bağlıdır. – sleske

    +0

    Tamamen katılıyorum. Ne tür bir yaklaşım, sadece resmin bir parçası olduğunda ve sorunun sadece bir parçası olmadığında net olabilir. Her iki şekilde de, döngüsel bağımlılık kolayca önlenebilir! – CKing