Başka bir soruna daha kolay bir çözüm getirirse, kod kokusu duymanız sorun olur mu? [kapalı]


31

Bir grup arkadaş ve ben kısa süredir bir proje üzerinde çalışıyoruz ve ürünümüze özgü bir senaryoyu temsil etmek için güzel bir OOP yöntemi icat etmek istedik. Temel olarak, Touhou tarzı bir mermi cehennemi oyunu üzerinde çalışıyoruz ve hayal edebileceğimiz herhangi bir mermi davranışını kolayca temsil edebileceğimiz bir sistem kurmak istedik.

Yani yaptığımız tam olarak buydu; Bir merminin davranışını istediğimiz gibi mermi örneklerine iliştirilebilecek farklı bileşenlere bölmemize izin veren gerçekten zarif bir mimari yaptık, bir nevi Birlik bileşen sistemi gibi. Güzelce çalıştı, kolayca genişletilebilir, esnek ve tüm üslerimizi kapsıyordu, ancak küçük bir sorun vardı.

Bizim uygulama aynı zamanda yüksek miktarda işlemsel üretim içerir, yani biz mermilerin davranışlarını usule göre üretiyoruz. Bu neden bir problem? Öyleyse, mermi davranışını temsil eden OOP çözümümüz zarif olsa da, insansız çalışmak için biraz karmaşık. İnsanlar hem mantıklı hem de zeki sorunların çözümlerini düşünecek kadar akıllıdır. Prosedürel üretim algoritmaları henüz o kadar akıllı değil ve OOP mimarisini kullanan bir AI'yi en yüksek potansiyele uygulamak için zor bulduk. Kuşkusuz, bu mimarinin bir kusuru, her durumda sezgisel olmamasıdır.

Bu sorunu çözmek için, temelde, farklı bileşenlerin sunduğu tüm davranışları mermi sınıfına ittik, böylece, hayal edebileceğimiz her şey, diğer ilişkili bileşen örneklerinin aksine, doğrudan her bir kurşun örneğinde sunuldu. Bu, prosedürel üretim algoritmalarımızın çalışmasını biraz kolaylaştırıyor, ancak şimdi kurşun sınıfımız çok büyük bir tanrı nesnesi . Kolayca programdaki en büyük sınıftır ve başka bir şeyden beş kat daha fazla kod içerir. Koruması da biraz acı verici.

Sınıflarımızdan birinin başka bir problemle çalışmayı kolaylaştırmak için bir tanrı nesnesine dönüşmesi sorun olmaz mı? Genel olarak, farklı bir soruna daha kolay bir çözüm getirirse, kodunuzda kod kokularınızın olması doğru olur mu?


1
Şey ... cevap vermek biraz zor. Bence NO. Özellikle diğer insanlarla birlikte çalışıyorsanız. Eğer yalnız çalışırsanız ne istersen yapabilirsin. Ancak genel olarak kiminle çalıştığınıza bağlıdır.
Sarcastic Patates

13
"Eğer aptalca ve işe yarıyorsa; aptalca değil." Bu söylendiği gibi, tam olarak istediğiniz gibi çalışsa bile, onu nasıl düzeltmeye karar verdiğinizden dolayı o tanrı sınıfına gelecekteki kodlamayı imkansız hale getirip getirmeyeceğinize dikkat etmek gerekir.
Flater

8
Koku alıp koktuğunu bilmek, daha sonra sadece diğer insanların farkına varmak koklamak daha iyidir. :)
Reactgular

1
İşlem kodunuza OO olmayan bir arayüz sağlayan bir adaptör sınıfına ihtiyacınız var gibi görünür, böylece kodunuzun geri kalanını temiz tutabilirsiniz (er).
nikie,

1
Harika bir sistem kurmuş gibi görünüyorsunuz ve hepsini cehenneme göndermeye karar verdiniz, şimdi bir özellik üzerinde beklendiği gibi çalışmıyor. Gerçekten istediğin bu mu? İşinle gurur duy!
Mast

Yanıtlar:


74

Gerçek dünyadaki programları oluştururken, bir yandan pragmatik kalmakla diğer yandan% 100 temiz kalmak arasında bir takas vardır. Temiz kalmanız, ürününüzü zamanında göndermenizi yasaklarsa, o zaman ddn kapısını kapıdan çıkarmak için bir miktar koli bandı ile daha iyi durumda olursunuz .

O, senin açıklama farklı sesler Said'in - bu Eklemek gidiş değildir sesler biraz sen daha iyi bir çözüm için uzun ve yeterince sert bakmadı çünkü bütün mimarisini mahvedecek gibi koli bandı biraz, bu sesler. Bu yüzden burada PSE'de size bu konuda bir nimettir veren birini aramak yerine, derinlemesine yaşadığınız sorunların bazı ayrıntılarını tanımladığınız farklı bir soru sorabilir ve birisinin size tanrıdan kaçan bir fikir önerip önermediğine bakabilirsiniz. sınıf yaklaşımı.

Belki de mermi sınıfı, bir grup başka sınıfa cepheli olarak tasarlanabilir, böylece mermi sınıfı daha küçük hale gelir. Belki strateji deseni, merminin farklı davranışları farklı strateji nesnelerine devretmesi için yardımcı olabilir. Belki de, kurşun bileşeniniz ve işlemsel jeneratörünüz arasında sadece bir adaptöre ihtiyacınız var. Ancak, dürüst olmak gerekirse, sisteminizin daha fazla ayrıntılarını bilmeden, sadece bir tahmin yapabilir.


6
Sadece bu cevabı tekrar doğrulamak için aynı iki tavsiyeyle bir şeyler yazacaktım. Son paragrafa ilişkin olarak, OP'nin tarif ettiği şey, bir başka dolaylı seviyeye ihtiyaç duyulduğunu belirten, kendi başına bir kod kokusu gibi görünmektedir. Bunun daha iyi bir fabrika sınıfı, cepheler veya AI'nın üretebileceği tam gelişmiş bir DSL olup olmadığı OP'ye bırakılmıştır.
Daniel B,

2
Kodu daha küçük parçalara bölmek için Cephe / Strateji üzerine iyi öneriler. Daha fazla ayrıntı bilmeden, ne önerileceğini bilmek zor.
user949300,

25

İlginç soru. Daha önceki deneyimlerimden dolayı biraz önyargılıyım.

Kısa cevap: Öğrenmeyi asla bırakmayız. Böyle bir duvara çarptığınızda, kodlama kokusu eklemek için bir mazeret değil, mimari / tasarım becerilerinizi geliştirmek için bir şanstır.

Uzun versiyon şu anda iş yerimdeki projelerimde pek çok kez benzer sorular soruluyor, fakat kaçınılmaz olarak, konuyu çok daha derinlemesine tartıştık, sonra asıl sorgulayıcı kredi verdi. Bunun gibi kök neden analizi gibi zihniyetleri dahil etmek istiyorsunuz.

5 Whys özellikle yararlı buldum . Buradaki açıklamanız, ilk neden gibi:

  • “Şimdi bu tanrı sınıfına sahibiz” Neden?
  • "Çünkü prosedürel üretim algoritmasını basitleştiriyor"

Tam olarak basitleştirilmiş olan nedir? Peki neden böyle? Bu çizgi boyunca ilerlemeye devam edin ve tipik olarak olan şey, daha temel problemleri anlamaya başlamanızdır, ancak aynı zamanda, size daha temel çözümler sunar.

Uzun lafın kısası, eldeki sorun ve özellikle nedenleri hakkında daha derinlemesine düşündükten sonra, benim deneyimime göre asıl soru tüm katılımcılara karşı tamamen boş ve son derece ilgisiz kaldı. Eğer şüpheleriniz varsa, onlara meydan okuyun; ya onlar gider, ya da ne yapmanız gerektiğini bilirsiniz. Dikkat edin, kod / tasarım hakkında bu şüphelere sahip olmak bence iyi bir işaret. Diğerleri buna içgüdüsel bir duygu diyor, ancak bu sorunlara meydan okumak için önce onları tanımanız gerekir. İlk adımı attığından beri tebrikler! Şimdi tavşan deliğinden aşağıya in ...


9

Bunun gibi bir tanrı sınıfına sahip olmak hiçbir zaman arzu edilmez, çünkü sadece mermilerinizin artık monolitik nesneler olduğu anlamına gelmez, aynı şey prosedürel üretim algoritmanız için de geçerlidir.

İlk adım analiz etmek, neden AI'nızın modelinizin karmaşıklığıyla başa çıkmak konusunda bu kadar çok sorunu olduğunu analiz etmek olurdu?

Tesadüfen, AI'nızı her olası özelliğin semantiğinin tam olarak farkında olan bir tanrı sınıf nesnesine dönüştürmeye çalıştınız mı? Bunu yaptıysanız, sorunun kaynağı budur.

Bu durumda, çözüm, tüm stratejileri mermi sınıfının kendisine entegre etmek yerine, AI'nın ipucunu AI çekirdeğinden strateji uygulamalarına indirgemek olmuştur.

Bu, eski davranışlarla yan etkilere girme korkusu olmadan sistemi istediğiniz gibi yeni stratejilerle genişletme seçeneği de dahil olmak üzere, başlangıçta istediğiniz esnekliği sağlayacaktır.

Bunun yerine, artık tanrı objeleriyle ilgili tüm sorunlara sahipsiniz: Sadece tanrı sınıfının kendisinin anlaşılması zor, monolitin hata ayıklanması zor değil, aynı şey böyle bir tanrı sınıfına erişen tüm diğer bileşenler için de geçerli. Soyutlamanın eksikliğinden dolayı, AI'nız, artık tüm gereksiz, bireysel özelliklerin farkında olmak zorunda olduğu gibi, benzer karmaşıklıktan vazgeçmek zorundadır.

Şu anda bile, bakım konusunda zaten sorun yaşıyorsunuz. Bu problemler daha da kötüye gidiyor, özellikle de bu sınıfın nasıl çalışması gerektiğine dair bilişsel bir modeli olan takım üyelerini kaybederseniz.

Şimdiye dek tanıştığım bu tanrı sınıflarını veya tanrı işlevlerini kullanan her bir proje ya sıfırdan tamamen yeniden yazıldı ya da durduruldu, istisnalar yoktu.


Ne kadar büyük ya da karmaşık sınıfların olması gerektiği konusundaki tartışmalarda sık sık eksik olan şey, “X türünde bir referansı tutan kodun bununla ne kadar yapması gerektiği” ve “dosyaya göre” sınıf dosyasında ne kadar mantık bulunması gerektiği arasındaki farktır. X". Bir müşteri muhtemelen çeşitli yetenekleri destekleyen (örneğin "yenilebilir") nesne koleksiyonlarına sahipse ve genellikle bir koleksiyonun tüm üyelerinden örneğin "mümkünse yenilebilir, başka hiçbir şey yapmaz", veya bir arayüze sahip olmasını isteme isteğinde bulunursa Bu tür birçok yöntemi birleştiren arayüzünü bölmeye çalışmaktan çok daha yararlı olabilir.
supercat,

Böyle bir arayüz göz önüne alındığında, kodun farklı kombinasyonları ayrı ayrı ele almak zorunda kalmadan herhangi bir yetenek kombinasyonu ile nesneleri kapsüllenmesi mümkündür. Arabirimleri ayırmak, birçok farklı proxy sınıfı yazmayı gerekli kılar; çünkü, X yöntemini destekleyen bir tür için proxy'ler, X'e sahip olmayan nesneleri sarmak için kullanılamaz ve X'in yapamayacağı nesneleri sarmak için proxy'ler kullanılamaz. X yöntemini, onu destekleyebilecek bir nesneyi sarsa bile gösteremedi.
supercat,

8

Zamanın başlangıcından bu yana bütün kötü kodların, adım adım makul görünmesini sağlayan evriminin ardında bir hikaye var. Seninki bir istisna değil. Kodlayıcılar kodlayarak öğrenirler. Sorununuzun şu anda açık görünen öngörülemeyeceğiniz yönleri var. Tamamen makul bir şekilde aldığınız kararlar var, ancak mimarinizi genel olarak yanlış yöne yönlendirdiniz. Bu kararları tanımlamanız ve yeniden gözden geçirmeniz gerekir.

Ofisinizde, insanların nasıl düzelteceklerine dair herhangi bir fikri olup olmadığını sorun. Çalıştığım çoğu yerde, programcıların yaklaşık% 10 - 20'si bu tür şeyler için gerçek bir yeteneğe sahipler ve sadece şansı bekliyorlardı. Bu insanların kim olduğunu bul. Çoğu zaman, alternatif mimariyi en kolay görebilen mevcut mimariye tarihsel olarak yatırım yapmayan yeni elemanlarınız. Onları gazilerinizden biriyle eşleştirdiğinizde, bir araya geldiklerinde şaşıracaksınız.


2

Bazı durumlarda bu kesinlikle kabul edilebilir. Bununla birlikte, hem prosedürel jenerasyon hem de hoş / ekli bileşen bileşenli davranış mimarinizi kullanarak iyi bir çözüm olmadığına inanmakta zorlanıyorum. Eğer mermi sınıfına yeni giren tüm davranışlar, tanrı nesnesi ile temiz mimarlık versiyonu arasında işlevsel bir fark yoktur. Prosedürel oluşturma algoritmalarınızın kullanılmasını bu kadar zorlaştıran şey neydi?

Yeni bir soru (belki de burada veya gamedev.stackexchange.com adresinde?), Proc ile birlikte mimarinizle ilgili hangi problemlerinizi çözdüğünüzü düşünüyorum. gen., gerçekten ilginç olurdu. Eğer yeni bir soru yaparsanız, burada bize bildirin!


3
Bir tanrı sınıfına sahip olmanın hem bireysel hem de otomatik kaynaklardan oluşan bir derleme değil, hem kabul edilebilir hem de arzu edilebilir olduğu bir duruma herhangi bir örnek verebilir misiniz?
Ext3h

Kabul edilebilir durumdayken, "Başka bir soruna daha kolay bir çözüm eklerse kod kokusu almak sorun olur mu?" Tanrı sınıfları genellikle kompozisyon kullanılarak kolayca çözülebilir. Ama evet, her zaman% 100 kurtulmaya değmeyecek kesin kod kokuları var. Sonunda, bazı pragmatizm işleri yapmak için gerekli :). (Bu, bir hevesle en iyi uygulamaları atmanız gerektiğini düşündüğüm anlamına gelmiyor. Çoğu yazılım evinin en iyi uygulamaları daha sıkı takip etmenin daha iyi olacağına inanıyorum).
Roy T.

0

İlham almak için, işlevsel programlamaya veya daha kesin olarak sıkı özel tiplere bakmak isteyebilirsiniz. İşlerin işe yaramadığı fikri, sahip olduğunuz tip sisteminde temsil etmek imkansızdır. Örneğin, "mermi vur" ve "mermi tut" bileşenlerine sahip bir silahınız olduğunu varsayalım. İki ayrı bileşense, mantıklı olmayan yapılandırmalar vardır - mermileri vuran ancak deposunda hiç bulunmayan bir silahınız veya mermileri depolayan ancak onları kovmayan bir silahınız olabilir.

Bu karmaşıklık düzeyinde, “doğru, bir insan bunun işe yaramaz olduğunu ve imkansız kombinasyonlardan kaçınacağını” düşünür. Bunu yapmanın imkansız hale getirilmesi daha iyi bir yol olabilir. Örneğin, "ateş kurşunlar" için bileşen olabilir gerektirir "tutma mermi" bileşeni başvuru (veya sadece olmasına rağmen kendi sorunları olduğunu, düpedüz kendisi bir parçası olarak tutun).

Örnekleriniz çok daha karmaşık olsa da, anahtar hala olası kombinasyonları sınırlandırıyor ve kısıtlamalar getiriyor. Bir şekilde, prosedürel jenerasyonun doğru olması için çok karmaşıksa, muhtemelen zaten çok karmaşıktır. Silahları tasarlarken kendinizi kısıtladığınız tüm yolları düşünün - kendinize “doğru, bu silahın zaten bir alev makinesi var, bir el bombası fırlatıcısı eklemenin bir anlamı yok” mu diyorsunuz? Bu, buluşsal bulgunuza dahil edebileceğiniz bir şey. Sadece her bir bileşene sahip olma şansını vermekten biraz daha karmaşık bir olasılık mekanizması kullanmak isteyebilirsiniz - birbirlerini dışlama eğiliminde olan bileşenlere veya birlikte iyi çalışmaya eğilimli bileşenlere sahip olabilirsiniz.

Ve son olarak, bunun gerçekten büyük bir problem olup olmadığını düşünün. Oyunun eğlencesini mahvediyor mu? Sonuç tabancaları işe yaramaz mı, yoksa aşırı mı güçlendi? Ne kadar? 10 saçmalıktan biri mi? Borderlands gibi oyunlar (usule göre oluşturulmuş silah efektleriyle birlikte) çoğu kez saçma sapan efekt kombinasyonlarını görmezden gelir - 16x kapsama alan av tüfeğine sahip olmanın amacı nedir? Ve yine de, Borderlands'da çok sık olur. Nesil mekanizmaların başarısızlığı olarak değerlendirilmek yerine, sadece gülmek için oynandı :)

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.