BobDalgleish zaten bu (anti-) desenin " tramp data " olarak adlandırıldığını kaydetti .
Tecrübelerime göre, aşırı serseri verilerinin en yaygın nedeni, bir nesnede veya veri yapısında gerçekten kapsanması gereken bir sürü bağlantılı durum değişkenine sahip olmasıdır. Bazen, verileri düzgün şekilde düzenlemek için bir grup nesneyi yerleştirmek bile gerekebilir.
Basit bir örnek için, gibi özelliklere sahip özelleştirilebilir bir oyuncu karakteri vardır bir oyun düşünün playerName
, playerEyeColor
böylece ve. Tabii ki, oyuncu oyun haritası üzerinde fiziksel bir konuma ve mevcut ve maksimum sağlık seviyesi gibi diğer özelliklere de sahiptir.
Böyle bir oyunun ilk adımında, tüm bu özellikleri global değişkenlere dönüştürmek mükemmel bir seçim olabilir - sonuçta, sadece bir oyuncu vardır ve oyundaki hemen hemen her şey bir şekilde oyuncuyu içerir. Dolayısıyla, küresel durumunuz aşağıdaki gibi değişkenler içerebilir:
playerName = "Bob"
playerEyeColor = GREEN
playerXPosition = -8
playerYPosition = 136
playerHealth = 100
playerMaxHealth = 100
Ancak bir noktada, belki de oyuna çok oyunculu bir mod eklemek istediğiniz için bu tasarımı değiştirmeniz gerekebileceğini fark edebilirsiniz. İlk girişim olarak, tüm bu değişkenleri yerel hale getirmeyi ve bunları gerektiren işlevlere geçirmeyi deneyebilirsiniz. Ancak, oyununuzdaki belirli bir eylemin aşağıdaki gibi bir işlev çağrısı zincirini içerdiğini görebilirsiniz:
mainGameLoop()
-> processInputEvent()
-> doPlayerAction()
-> movePlayer()
-> checkCollision()
-> interactWithNPC()
-> interactWithShopkeeper()
... ve interactWithShopkeeper()
işlev sahibinin oyuncuyu ismiyle ele aldığından, aniden tüm bu işlevler playerName
arasında serseri verileri olarak geçmeniz gerekir . Ve tabii ki, dükkan sahibi mavi gözlü oyuncuların saf olmadığını düşünüyorsa ve onlar için daha yüksek fiyatlar talep ederse, o zaman tüm fonksiyonlar zincirinden geçmeniz gerekir .playerEyeColor
Uygun çözüm, bu durumda, adını kapsüller bir oyuncu nesnesini tanımlamak için elbette, göz rengi, pozisyon, sağlık ve oyuncu karakterin başka özelliklerinin olduğunu. Bu şekilde, o tek nesneyi bir şekilde oynatıcıyı içeren tüm fonksiyonlara geçirmeniz yeterlidir.
Ayrıca, yukarıdaki işlevlerin birçoğu doğal olarak o oyuncu nesnesinin yöntemlerine dönüştürülebilir ve bu da otomatik olarak oyuncuların özelliklerine erişmelerini sağlar. Bir şekilde, bu sadece sözdizimsel bir şekerdir, çünkü bir nesneyle ilgili bir yöntemi çağırmak, nesneyi etkin bir şekilde gizli bir parametre olarak nesneyi etkin bir şekilde ilettiğinden, ancak kodu doğru kullanıldığında daha net ve daha doğal görünmesini sağlar.
Tabii ki, tipik bir oyun, sadece oyuncudan çok daha fazla "küresel" duruma sahip olacaktı; örneğin, neredeyse kesinlikle oyunun gerçekleştiği bir tür haritaya ve harita üzerinde hareket eden oyuncu olmayan karakterlerin bir listesine ve belki de üzerine yerleştirilen nesnelere vb. sahip olabilirsiniz. Bunların hepsini tramp nesnesi olarak da geçirebilirsiniz, ancak bu, yöntem argümanlarınızı yeniden karıştırır.
Bunun yerine, çözüm nesnelerin kalıcı veya geçici ilişkileri olan diğer nesnelere referansları saklamasını sağlamaktır. Bu nedenle, örneğin, oyuncu nesnesi (ve muhtemelen herhangi bir NPC nesnesi de) muhtemelen geçerli seviye / haritaya atıfta bulunacak olan "oyun dünyası" nesnesine bir referans kaydetmelidir, böylece böyle bir yöntemin player.moveTo(x, y)
gerekmesi gerekmez açıkça haritaya bir parametre olarak verilecek.
Benzer şekilde, eğer oyuncu karakterimiz, onları takip eden evcil bir köpeğe sahip olsaydı, köpeği tanımlayan tüm durum değişkenlerini tek bir nesnede doğal olarak gruplandırırdık ve oyuncu nesnesine köpeğe bir referans verdik (böylece oyuncu , köpeği ismiyle çağırın) ve tersi (köpeğin oyuncunun nerede olduğunu bilmesi için). Ve elbette, oyuncuyu ve köpeği daha genel bir "aktör" nesnesinin her iki alt sınıfına da nesneler yapmak isterdik, böylece aynı kodu her iki harita üzerinde hareket ettirmek için de aynı kodu tekrar kullanabiliriz.
Ps. Bir oyunu örnek olarak kullanmama rağmen, bu tür sorunların ortaya çıktığı başka tür programlar da var. Benim tecrübelerime göre, altta yatan problem her zaman aynı olma eğilimindedir: gerçekten bir veya daha fazla birbirine bağlı nesnede bir araya getirilmek isteyen bir dizi ayrı değişken (yerel veya global). İşlevlerinize izinsiz giren "tramp data", "global" seçenek ayarlarından veya önbelleğe alınmış veritabanı sorgularından veya durum vektörlerinden sayısal bir simülasyonda olsun, çözüm her zaman verilerin ait olduğu doğal içeriği tanımlamak ve bunu bir nesneye dönüştürmek içindir. (veya seçtiğiniz dilde en yakın eşdeğer neyse).