Oyun geliştirmek için mümkün olan nesne mirasını kullanmaktan kaçınmalı mıyım?


36

Unity ile oyun geliştirirken OOP özelliklerini tercih ediyorum. Genellikle bir temel sınıf yaratırım (çoğunlukla soyutlanır) ve aynı işlevselliği diğer çeşitli nesnelerle paylaşmak için nesne kalıtımı kullanırım.

Ancak, geçenlerde birinden miras kullanımından kaçınılması gerektiğini ve bunun yerine arayüzleri kullanmamız gerektiğini duydum. Bu yüzden neden diye sordum ve “Nesne devralma elbette önemlidir, ancak çok sayıda genişletilmiş nesne varsa, sınıflar arasındaki ilişki derin bir birleşti.

Ben, böyle bir şey bir soyut temel sınıf kullanıyorum WeaponBaseve benzeri spesifik silah sınıfları oluşturarak Shotgun, AssaultRifle, Machinegunböyle bir şey. Çok fazla avantaj var ve gerçekten zevk aldığım tek örnek çok biçimlilik. Alt sınıfların yarattığı nesneyi temel sınıfmış gibi ele alabilirim, böylece mantık büyük ölçüde azaltılabilir ve yeniden kullanılabilir hale getirilebilir. Alt sınıfın alanlarına veya yöntemlerine erişmem gerekiyorsa, alt sınıfa geri döndüm.

Ben genellikle farklı sınıflardan, kullanılan aynı alanları tanımlamak için istemiyormuş gibi AudioSource/ Rigidbody/ Animatorve ben gibi tanımlanmış üye alanlarının çok fireRate, damage, range, spreadvb. Ayrıca bazı durumlarda, bazı yöntemlerin üzerine yazılabilir. Bu yüzden bu durumda sanal yöntemler kullanıyorum, bu yüzden temelde bu yöntemi ebeveyn sınıfından yöntemi kullanarak çağırabilirim, ancak mantık çocuklarda farklıysa, bunları el ile geçersiz kıldım.

Öyleyse, tüm bunlar kötü uygulamalar olarak terk edilmeli mi? Bunun yerine arayüzleri kullanmalı mıyım?


30
“Çok fazla avantaj var ve gerçekten zevk aldığım tek örnek çok biçimlilik.” Polimorfizm bir kalıp değildir. Kelimenin tam anlamıyla OOP'un bütün noktası. Ortak alanlar vb. Gibi diğer şeyler, kod çoğaltma veya devralma olmadan kolayca elde edilebilir.
Kübik

3
Arayüzleri öneren kişi mirastan daha iyiydi, size herhangi bir argüman verdi mi? Merak ediyorum.
Hawker65

1
@ Cubic Polimorfizmin bir örüntü olduğunu asla söylemedim. Dedim ki, "... gerçekten zevk aldığım tek biçim polimorfizm". Gerçekten zevk aldığım örüntü, polimorfizm değil, "polimorfizm" kullanıyor demektir.
Modernator

4
İnsanlar miras üzerinden ara yüzleri herhangi bir gelişme biçiminde kullanmak zorunda kalırlar. Bununla birlikte, çok fazla genel gider, bilişsel uyumsuzluk eklemeye meyillidir, sınıf patlamasına yol açar, sıklıkla sorgulanabilir bir değer katar ve genellikle projede HERKESİ arayüzlere odaklanmayı takip etmediği sürece bir sistemde iyi bir şekilde birleşmez. Yani mirastan henüz vazgeçme. Ancak, oyunların kendine has özellikleri var ve Unity'nin mimarisi sizden CES tasarım paradigmasını kullanmanızı bekliyor; bu yüzden yaklaşımınızı değiştirmelisiniz. Oyun türü sorunlarını anlatan Eric Lippert'in Büyücüleri ve Savaşçıları serisini okuyun.
Dunk

2
Bir arayüzün, temel sınıfın veri alanı içermediği belirli bir miras vakası olduğunu söyleyebilirim. Bence öneri, her nesnenin sınıflandırılması gereken devasa bir ağaç yapmamaya çalışmak yerine, çoklu kalıtımdan yararlanabileceğiniz arayüzlere dayanan çok sayıda küçük ağaç oluşturmaya çalışmak olduğunu düşünüyorum. Polimorfizm, arayüzlerle kaybolmaz.
Emanuele Paolini,

Yanıtlar:


65

Varlığınızdaki miras ve envanter / kalem sistemlerindeki kompozisyonu tercih edin. Bu tavsiye, oyun mantığı yapılarına uygulanmaya meyillidir; bu, karmaşık şeyleri (çalışma zamanında) birçok farklı kombinasyona götürebilir; İşte o zaman kompozisyonu tercih ediyoruz.

Uygulama düzeyinde mantığınızdaki kompozisyona göre mirastan yararlanın , UI inşaatlarından hizmetlere kadar her şey. Örneğin,

Widget->Button->SpinnerButton veya

ConnectionManager->TCPConnectionManagervs ->UDPConnectionManager.

... burada çok sayıda potansiyel türevden ziyade açıkça tanımlanmış bir türev hiyerarşisi var, bu yüzden miras kullanımı daha kolay.

Alt satır : Yapabildiğiniz yerlerde miras alın, ama gereken yerlerde kompozisyon kullanın. PS Varlık sistemlerinde kompozisyonu tercih etmemizin diğer nedeni, genellikle birçok varlığın olmasıdır ve miras, her nesnede üyelere erişmek için performans maliyetine neden olabilir; vtables bakın .


10
Kalıtım, tüm yöntemlerin sanal olacağı anlamına gelmez. Bu yüzden otomatik olarak performans maliyetine yol açmaz. VTable , veri üyelerine erişimde değil , sanal aramaların gönderilmesinde rol oynar .
Ruslan

1
@Ruslan Yorumunuzu yapmak için 'may' ve 'can' kelimelerini ekledim. Aksi halde, cevabı kısa tutmanın menfaatleri doğrultusunda, fazla ayrıntıya girmedim. Teşekkürler.
Mühendisi

7
P.S. The other reason we may favour composition in entity systems is ... performance: Bu gerçekten doğru mu? @Linaith'in bağladığı Vikipedi sayfasına bakıldığında, arayüzler nesnesini oluşturmanız gerekeceğini gösterir. Bu nedenle, başka bir dolaylı yönlendirme seviyesini tanıttığınız için sanal işlev çağrıları ve daha fazla önbellek özeti (hala veya daha fazlası) vardır.
Flamefire

1
@ Flamefire Evet, doğru; Verilerinizi, önbellek verimliliğinizin ne olursa olsun, optimum ve kesinlikle bu ekstra yüklemelerden çok daha uygun olacağı şekilde düzenlemenin yolları vardır. Bu değildir kalıtım ve vardır dizi-of-yapı / yapı-of-the dizileri anlamda daha (içiçe / karıştırılmamış önbellek doğrusal bir düzenlemede veri), bölme ayrı diziler ve bazen setleri aynı veri çoğaltma olsa bileşim Boru hattınızın farklı bölümlerindeki işlemlerin listesi. Ancak bir kez daha, bu konuya girilmesi, kararın iyiliği için kaçınılması gereken çok büyük bir sapma olacaktır.
Mühendis

2
Lütfen açıklama veya eleştiriye ilişkin sivil taleplere ilişkin yorumları saklamayı unutmayın ve fikirlerini ifade eden kişinin karakterini veya deneyimini değil, fikirlerin içeriğini tartışın.
Josh

18

Zaten birkaç güzel cevabın var, ama sorunuzdaki odadaki dev fil şu:

miras kullanımından kaçınılması gereken birinden duydum ve bunun yerine arayüzleri kullanmalıyız.

Bir kural olarak, birileri size bir kural getirdiğinde, görmezden gelin. Bu sadece "birileri size bir şey söylüyor" için değil aynı zamanda internette bir şeyler okumak için de geçerli. Nedenini bilmiyorsanız (ve arkasında durabiliyorsanız), bu tür bir tavsiye değersizdir ve genellikle çok zararlıdır.

Tecrübelerime göre, OOP'deki en önemli ve faydalı kavramlar "düşük eşleşme" ve "yüksek uyum" (sınıflar / nesneler birbirleri hakkında mümkün olduğunca az şey bilir ve her birim mümkün olan en az şeyden sorumludur).

Düşük kavrama

Bu, kodunuzdaki herhangi bir "malzeme grubunun" çevresine mümkün olduğu kadar az bağlı olması gerektiği anlamına gelir. Bu, sınıflar (sınıf tasarımı), aynı zamanda nesneler (gerçek uygulama), genel olarak "dosyalar" (yani, #includeher bir .cppdosya için s sayısı, importher bir .javadosya başına sayı vb.) İçin de geçerlidir.

İki varlığın birleştiğinin bir işareti, diğerinin herhangi bir şekilde değiştirilmesi durumunda, birinin kırılacağına (veya değiştirilmesi gerektiğine) işarettir.

Kalıtım açık bir şekilde birleşmeyi artırır; temel sınıfın değiştirilmesi tüm alt sınıfları değiştirir.

Arayüzler kuplajı azaltır: açık, yöntem tabanlı bir sözleşme tanımlayarak, sözleşmeyi değiştirmediğiniz sürece arayüzün her iki tarafıyla ilgili her şeyi özgürce değiştirebilirsiniz. ("Arayüz" genel bir kavramdır, Java interfaceveya C ++ soyut sınıfları sadece uygulama detaylarıdır).

Yüksek uyum

Bu, her bir sınıf, nesne, dosya vb. İle mümkün olduğu kadar az ilgilenmek veya sorumlu olmak demektir. Yani, birçok şey yapan büyük derslerden kaçının. Örneğinizde, silahlarınızın tamamen ayrı yönleri varsa (cephane, ateşleme davranışı, grafik gösterimi, envanter gösterimi vb.), O zaman bunlardan birini temsil eden farklı sınıflara sahip olabilirsiniz. Ana silah sınıfı daha sonra bu ayrıntıların bir "sahibine" dönüşür; Bir silah nesnesi o zaman bu ayrıntılara bir kaç işaretten biraz daha fazlasıdır.

Bu örnekte, "Ateşleme Davranışı" nı temsil eden sınıfınızın ana silah sınıfı hakkında insanca mümkün olduğu kadar az şey bildiğinden emin olabilirsiniz. Optimal olarak, hiçbir şey. Bu, örneğin, dünyanızdaki herhangi bir nesneye (taretler, volkanlar, NPC'ler ...) sadece bir parmağınızla "Ateşleme Davranışı" verebileceğiniz anlamına gelir . Bir noktada, silahların envanterde temsil edilme şeklini değiştirmek istiyorsanız, o zaman basitçe bunu yapabilirsiniz - sadece envanter sınıfınız bunu bilir.

Bir varlığın uyumlu olmadığının bir işareti, aynı anda birkaç yöne doğru dallanıp büyüyüp büyümesidir.

Tanımladığın gibi kalıtım, bağlılığı azaltır - silah sınıflarınız, günün sonunda silahlarınızın her türlü farklı, ilişkili olmayan yönünü ele alan büyük parçalardır.

Arayüzler, arayüzün iki tarafı arasındaki sorumlulukları net bir şekilde bölerek uyumu dolaylı olarak arttırır.

şimdi ne yapmalı

Hala kesin ve hızlı kurallar yok, bunların hepsi sadece kurallar. Genel olarak, TKK kullanıcısı cevabında belirttiği gibi, kalıtım okulda ve kitaplarda çokça öğretilir; OOP ile ilgili süslü şeyler. Arayüzler öğretmek için muhtemelen daha sıkıcıdır ve ayrıca (önemsiz örnekleri geçerseniz) kalıtım kadar açık olmayan bağımlılık enjeksiyon alanını açmak biraz daha zordur.

Günün sonunda, kalıtım temelli planınız net bir OOP tasarımına sahip olmamaktan daha iyidir. Bu yüzden ona bağlı kalmaktan çekinmeyin. İsterseniz, Düşük Kuplaj, Yüksek Uyum hakkında biraz ruminasyon yapabilir / google'da dolaşabilir ve bu tür bir düşünceyi cephaneliğinize eklemek isteyip istemediğinizi görebilirsiniz. İsterseniz daha sonra denemek için her zaman yeniden deneyimleyebilirsiniz; veya bir sonraki daha büyük yeni kod modülünüzde arayüz tabanlı yaklaşımları deneyin.


Ayrıntılı açıklama için teşekkür ederiz. Neyi özlediğimi anlamak gerçekten çok yararlı.
Modernator

13

Mirastan kaçınılması gerektiği fikri basitçe yanlıştır.

Kalıtım Üzerine Kompozisyon adlı bir kodlama prensibi vardır . Kompozisyonla aynı şeyleri başarabileceğinizi söylüyor ve bu tercih edilir çünkü bazı kodları yeniden kullanabilirsiniz. Bkz Ben miras üzerinde kompozisyon tercih etmeliyiz Neden?

Silah sınıflarını beğendim ve aynı şekilde mi yapacağımı söylemeliyim. Ama şu ana kadar bir oyun yapmadım.

James Trotter'in belirttiği gibi, kompozisyonun, özellikle silahın çalışma şeklini değiştirme konusundaki esnekliğinde bazı avantajları olabilir. Miras ile mümkün olabilirdi, ama daha zor.


14
Yine de, silahlar için sınıflara sahip olmak yerine, tek bir "silah" sınıfına ve hangi ateşlemenin yapıldığını, hangi eklere sahip olduklarını ve ne yaptıklarına, ne "cephane deposuna" sahip olacağınıza dair birçok konfigürasyon oluşturabilirsiniz. bunlardan bazıları "av tüfeği" veya "saldırı tüfeği" olabilir, ancak çalışma zamanlarında örneğin ek parçaların değiştirilmesi ve dergi kapasitelerinin değiştirilmesi vb. için de değiştirilebilir. Veya, silahların tamamen yeni konfigürasyonları oluşturulabilir. başlangıçta bile düşünmedim. Evet, mirasla benzer bir şeyi başarabilirsiniz, ancak o kadar kolay değil.
Trotski94

3
@JamesTrotter Bu noktada, Borderlands ve silahlarını düşünüyorum ve bunun sadece kalıtımla ne gibi bir canavarlık olacağını merak ediyorum ...
Baldrickk

1
@JamesTrotter Ben bir cevap ve bir yorum olsaydı keşke.
Pharap

6

Sorun, kalıtımın eşleşmeye yol açmasıdır - nesneleriniz birbirleri hakkında daha fazla bilgi sahibi olmalıdır. Bu yüzden kural “Mirasa karşı her zaman bileşimi tercih et” şeklindedir. Bu, ASLA ASLA miras kullanma anlamına gelmez, bu tamamen uygun olduğu yerde kullanmak anlamına gelir, ancak orada oturuyorsanız, "Bunu her iki şekilde de yapabilirim ve her ikisi de bir anlam ifade eder" diye düşünürseniz, doğrudan kompozisyona gidin.

Kalıtım ayrıca bir çeşit sınırlayıcı olabilir. Bir AssultRifle - olabilecek harika bir "WeaponBase" e sahipsin. Çift namlulu bir av tüfeğiniz varsa ve namluların bağımsız olarak ateş etmesine izin vermek istediğinizde ne olur - biraz daha sert ama yapılabilir, sadece tek namlulu ve iki namlulu bir sınıfa sahipsiniz, ancak 2 tek namlu monte edemezsiniz aynı silahta, yapabilir misin? Birini 3 varile sahip olarak ayarlayabilir misin yoksa bunun için yeni bir sınıfa mı ihtiyacın var?

Altında bir GrenadeLauncher ile bir AssultRifle hakkında - hmm, biraz daha sert. GrenadeLauncher'ı gece avcılığı için bir el feneriyle değiştirebilir misiniz?

Son olarak, bir yapılandırma dosyasını düzenleyerek kullanıcınızın önceki silahları yapmasına nasıl izin verirsiniz? Bu zordur, çünkü verilerle oluşturulmuş ve yapılandırılmış daha iyi kodlanmış ilişkileriniz vardır.

Birden fazla kalıtım, bu önemsiz örneklerin bir kısmını bir miktar düzeltebilir, ancak kendi sorun kümesini ekler.

"Kalıtım yerine kompozisyonu tercih et" gibi ortak sözler olmadan önce bunu, aşırı karmaşık bir kalıtım ağacı yazarak (ki bu harika bir eğlenceliydi ve mükemmel çalıştığını) sonra da daha sonra değiştirmenin ve sürdürmenin gerçekten zor olduğunu keşfettim. Söylemek istediğim, böyle bir kavramı tüm deneyimden geçmek zorunda kalmadan öğrenmek ve hatırlamak için alternatif ve kompakt bir yolunuz var - ama mirası yoğun bir şekilde kullanmak istiyorsanız, açık fikirli olmanızı ve ne kadar iyi çalıştığını değerlendirmenizi öneririm. sizin için - mirası yoğun bir şekilde kullanırsanız ve en kötü ihtimalle harika bir öğrenme deneyimi olabilirse (en iyi ihtimalle sizin için işe yarayabilir)


2
"Kullanıcınızın bir config dosyasını düzenleyerek önceki silahları yapmalarına nasıl izin veriyorsunuz?" -> Genelde yaptığım kalıp, her silah için son bir sınıf yaratmak. Örneğin, Glock17 gibi. İlk önce WeaponBase sınıfını oluşturun. Bu sınıf soyutlanmıştır, ateş modu, ateş hızı, dergi büyüklüğü, maksimum cephane, topaklar gibi ortak değerleri tanımlar. Ayrıca mouse1 / mouse2 / yeniden yükle gibi kullanıcı girdisini de kullanır ve karşılık gelen yöntemi çağırır. Neredeyse sanaldırlar veya daha fazla işleve bölünmüşlerdir, böylece geliştirici gerektiğinde temel işlevleri geçersiz kılabilir. Ve sonra WeaponBase'i genişleten başka bir sınıf oluşturun,
modernatör

2
SlideStoppableWeapon gibi bir şey. Tabancaların çoğu buna sahiptir ve bu, kayma durması gibi ek davranışları yerine getirir. Sonunda SlideStoppableWeapon'dan uzanan Glock17 sınıfı yaratın. Glock17, eğer tabanca sadece sahip olduğu ve sonunda buraya yazılan eşsiz bir yeteneğe sahipse, son sınıftır. Tabanca özel yangın mekanizması veya yeniden yükleme mekanizması olduğunda genellikle bu deseni kullanırım. Bu benzersiz davranışı sınıf hiyerarşisinin sonuna kadar uygulayın, ortak mantığı ebeveynlerden mümkün olduğunca birleştirin.
Modernator

2
@modernator Söylediğim gibi, sadece bir rehber - güvenmiyorsanız, görmezden gelmekten çekinmeyin, gözlerinizi zaman içinde sonuçlara açık tutun ve faydaları ve ağrıyı her zaman sıkça değerlendirin. Parmak uçlarımı bastırıp attığım yerleri hatırlamaya çalışıyorum ve başkalarının da aynı şeylerden uzak durmasına yardım ediyorum, ama benim için işe yarayan şey sizin için işe yaramayabilir.
Bill K,

7
@modernator Minecraft'ta Monsterbir alt sınıf oluşturdular WalkingEntity. Sonra sıska eklediler. Bunun işe yarayacağını ne kadar iyi düşünüyorsun?
user253751,

1
@ immibis Bu soruna bir referans veya anekdot bağlantınız var mı? Google minecraft anahtar kelimeleri beni video bağlantılarında boğuyor ;-)
Peter - Reinstate Monica

3

Diğer cevapların aksine, bunun mirasa karşı kompozisyon ile ilgisi yoktur. Mirasa karşı kompozisyon, bir sınıfın nasıl uygulanacağına dair verdiğiniz bir karardır. Arayüzler ve sınıflar bundan önce gelen bir karardır.

Arayüzler, herhangi bir OOP dilinin birinci sınıf vatandaşlarıdır. Sınıflar ikincil uygulama ayrıntılarıdır. Yeni programcıların zihinleri, arayüzler öncesi sınıfları ve mirası tanıtan öğretmenler ve kitaplar tarafından ciddi şekilde çarpıtılmaktadır.

Temel ilke, mümkün olduğunda tüm yöntem parametrelerinin ve dönüş değerlerinin türlerinin sınıflar değil arayüzler olması gerektiğidir. Bu, API'lerinizi daha esnek ve güçlü kılar. Zamanın büyük çoğunluğu, yöntemleriniz ve arayanların, uğraştıkları nesnelerin gerçek sınıflarını bilmek veya ilgilenmek için hiçbir nedenleri olmamalıdır. Eğer API'niz uygulama detayları konusunda agnostik ise, herhangi bir şeyi bozmadan kompozisyon ve kalıtım arasında serbestçe geçiş yapabilirsiniz.


Arayüzler herhangi bir OOP dilinin birinci sınıf vatandaşı ise, Python, Ruby, …'nin OOP dili olmadığını merak ediyorum.
BlackJack

@ BlackJack: Ruby'de arabirim örtüktür (eğer istersen ördek yazıyor) ve kalıtım yerine kompozisyon kullanarak ifade ediyor (ayrıca, ilgilendiğim kadarıyla aralarında bir yerde olan Mixins var)
AnoE

@ BlackJack "Arayüz" (kavram) gerektirmez interface(dil anahtar sözcüğü).
Caleth,

2
@Caleth Ama onları birinci sınıf vatandaş olarak adlandırmak IMHO yok. Bir dil tanımı bir şeyin birinci sınıf vatandaş olduğunu iddia ettiğinde, genellikle o dilde bir türü ve değeri olan ve geçirilebilecek gerçek bir şey olduğu anlamına gelir. Sınıflar gibi Python'da da birinci sınıf vatandaşlar, işlevler, yöntemler ve modüller gibi. Konsept hakkında konuşuyorsak, arayüzler OOP dışı dillerin de bir parçası.
BlackJack

2

Birisi size belirli bir yaklaşımın tüm durumlar için en iyisi olduğunu söylese, aynı ilacın tüm hastalıkları iyileştirdiğini söylemekle aynı şeydir.

Mirasa karşı kompozisyon, bir-a-a-bir sorudur. Arayüzler, bazı durumlar için uygun bir başka (3.) yoldur.

Kalıtım ya da is-a mantığı: yeni sınıfın harekete geçeceği zaman kullanıyorsunuz ve tamamen yeni bir sınıfa maruz kalacaksanız, onu türettiğiniz eski sınıf gibi (dışa doğru) kullanıyorsunuz. eski sınıfın sahip olduğu tüm işlevler ... o zaman sen miras kaldın.

Kompozisyon ya da has-a mantığı: Yeni sınıfın eski sınıfın özelliklerini halka açık olarak göstermeden eski sınıfı dahili olarak kullanması gerekiyorsa, kompozisyonu kullanırsınız, yani eski sınıfın bir örneğini üye özelliği veya yenisinin bir değişkeni. (Bu, kullanım durumuna bağlı olarak özel bir mülk olabilir veya korunabilir veya ne olursa olsun olabilir). Buradaki kilit nokta, orjinal sınıf özelliklerini göstermek ve halka kullanmak istemediğiniz, bunun sadece dahili olarak kullandığı, miras durumunda bunları halka açıkladığınız durumlarda kullandığı durumdur. yeni sınıf Bazen bir yaklaşıma, bazen de diğerine ihtiyaç duyarsınız.

Arayüzler: Arayüzler, başka bir kullanım durumu için geçerlidir - yeni sınıfın kısmen eski hale getirilmesini ve tamamen eski olanın işlevselliğini kamuoyuna açıklamasını istemiyorsanız . Bu, eskiden tamamen farklı bir hiyerarşiden yeni bir sınıfa, sadece bazı yönlerde eski gibi davranmanıza olanak tanır.

Diyelim ki sınıflarla temsil edilen çeşitli yaratıklar var ve onların fonksiyonlarla temsil edilen işlevleri var. Örneğin, bir kuş Talk (), Fly () ve Poop () olur. Sınıf Ördek tüm özellikleri uygulayarak Kuş sınıfından miras alırdı.

Sınıf Fox, belli ki uçamaz. Eğer atayı tüm özelliklere sahip olacak şekilde tanımlarsanız, soydan doğru bir şekilde türetemezsiniz.

Bununla birlikte, özellikleri bir arayüze sahip her çağrı grubunu temsil eden gruplara bölerseniz, örneğin, IFly, Takeoff (), FlapWings () ve Land () komutunu içeren bir örnek alırsanız, Fox'un ITalk ve IPoop işlevlerini uygulayabilirsiniz. ancak IFly değil. Daha sonra, belirli bir arayüz uygulayan nesneleri kabul etmek için değişkenleri ve parametreleri tanımlayacaksınız ve daha sonra onlarla çalışan kod neyin arayabileceğini ve diğer fonksiyonların da olup olmadığını görmesi gerekiyorsa diğer arayüzleri sorgulayabilecektir. geçerli nesne için uygulanır.

Bu yaklaşımların her birinin en iyisi olduğu durumlarda, hiç bir yaklaşım tüm durumlar için mutlak en iyi çözüm değildir.


1

Bir oyun için, özellikle varlık-bileşen mimarisi ile çalışan Unity ile oyun bileşenleriniz için mirasa ilişkin kompozisyonu tercih etmeniz gerekir. Çok daha esnektir ve bir oyun varlığının miras ağacının farklı yaprakları üzerinde iki şey "olmasını" istediğiniz bir duruma girmekten kaçınır.

Örneğin, bir miras ağacının bir dalında TalkingAI’niz ve başka bir ayrı dalda VolumetricCloud’un olduğunu ve konuşan bir bulut istediğinizi varsayalım. Bu, derin bir miras ağacında zordur. Varlık bileşeniyle, yalnızca TalkingAI ve Cloud bileşenlerine sahip bir varlık yaratırsınız ve gitmeniz iyi olur.

Ancak bu, yani, hacimsel bulut uygulamanızda, miras kullanmamanız gerektiği anlamına gelmez. Bunun için kod önemli olabilir ve birkaç sınıftan oluşabilir ve bunun için gereken OOP'yi kullanabilirsiniz. Fakat hepsi tek bir oyun bileşenine denk gelecek.

Yan not olarak, bu konuda bazı sorunlar alıyorum:

Genellikle bir temel sınıf yaratırım (çoğunlukla soyutlanır) ve aynı işlevselliği diğer çeşitli nesnelerle paylaşmak için nesne kalıtımı kullanırım.

Kalıtım kodun yeniden kullanımı için değildir. Bir ilişki kurmak için . Bunların çoğu el ele gider, fakat dikkatli olmalısınız. Sadece iki modülün aynı kodu kullanması gerekebileceği için, birinin diğeriyle aynı tipte olduğu anlamına gelmez.

İçinde List<IWeapon>farklı silah türleri olan bir silah kullanmak istiyorsanız, arayüzleri kullanabilirsiniz . Bu şekilde, hem IWeapon arabiriminden hem de tüm silahlar için MonoBehaviour alt sınıfından miras alabilir ve çoklu kalıtımın bulunmadığı sorunlardan kaçınabilirsiniz.


-3

Arayüzün ne olduğunu veya ne yaptığını anlamıyor gibisiniz. OO'yu düşünmek yaklaşık 10 yıldan fazla sürdü ve bazı akıllı insanlara sorular sormak ara yüzlerle ah-ha bir an yaşayabiliyor olmuştu. Bu yardımcı olur umarım.

En iyisi, bunların bir kombinasyonunu kullanmaktır. Benim OO aklımda dünyayı ve insanları modellemek derim ki bazı derin örnekler. Ruh bedenle zihinle etkileşime girer. Akıl, ruh (bazıları aklı düşünür) ve vücuda verdiği komutlar arasındaki arayüzdür. Vücudun zihinsel arayüzü, işlevsel olarak konuşan tüm insanlar için aynıdır.

Aynı benzetme, dünya ile etkileşime giren kişi (beden ve ruh) arasında kullanılabilir. Beden zihin ve dünya arasındaki arayüzdür. Herkes dünyaya aynı şekilde arayüzler kurar, tek özgünlük dünya ile NASIL etkileşime girdiğimizdir, MIND kullanarak dünyayı nasıl arabirim kurduğumuzu / etkileşimde bulunduğumuzu belirleriz.

Bir arayüz daha sonra OO yapınızı başka bir farklı OO yapısı ile ilişkilendirmek için bir mekanizmadır, her iki taraf da farklı bir ortam / ortamda bazı fonksiyonel çıktılar üretmek için birbirleriyle anlaşmalı / eşleşmesi gereken farklı özelliklere sahiptir.

Bu nedenle açık el işlevini çağırmak için nervous_command_system arabirimini, açık el çağırmadan önce gerekli tüm gereklilikleri nasıl uygulayacağınızla birlikte kendi API'sine sahip olan THAT ile uygulamalıdır.

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.