XNA Oyun Hizmetleri ile yüceltilmiş küresel değişkenler arasındaki fark nedir?


10

Microsoft.Xna.Framework.GameSınıf vardır Hizmetler programcı sınıfın tipini ve Ekle yöntemine sınıfının bir örneğini sunarak oyuna bir hizmet eklemenizi sağlar özelliği.

Şimdi, AudioComponentbunu gerektiren tüm sınıflara ve yöntemlere geçmek zorunda kalmak yerine, Gameörneğin örneğinizi iletip hizmeti ararsınız. ( Servis Bulucu )

Şimdi, oyunların birçok hizmeti (GraphicsDevice, SceneGraph, AudioComponent, EffectsManager, et cetera) olduğundan, temelde Oyunu her şeye geçireceksiniz.

Öyleyse neden bu örnekleri sadece bir Singleton yapmıyoruz? Çünkü, Singletons kötü çünkü küresel bir duruma sahipler, test etmeyi önlüyorlar ve tasarımınızı daha kırılgan hale getiriyorlar. Hizmet konum belirleyicileri eşit olarak birçok kişiye karşı anti-desen olarak kabul edilir, çünkü sadece bir nesneye bağımlılığı geçmek yerine, bu sınıfı hizmetlerin geri kalanıyla birleştiren bir hizmet konum belirleyicisini (Oyun) geçirirsiniz.

Öyleyse neden Hizmetler XNA ve oyun geliştirmede öneriliyor? Oyunlar normal programlardan farklı olduğu ve bileşenleriyle iç içe geçmiş olması ve bir sınıfın işleyişi için gerekli olan her bileşeni geçmek zorunda kalması son derece hantaldır mı? Oyun Hizmetleri o zaman oyun tasarımında gerekli bir kötülük mü? Uzun parametre listeleri ve kuplajı içermeyen alternatifler var mı?


3
"Hizmet konum belirleyicileri eşit olarak birçok kişi için bir anti-desen olarak kabul edilir" - [alıntı gerekli]. Açıkçası onları ihtiyaç duymadığınız yerlerde kullanmak kötüdür - tüm yazılım yapıları için doğrudur - ancak anti-desen adı verilen servis bulma araçlarını hiç duymadım. (Öte yandan, zamanlarının çoğunu en son model minutiae'yi tartışmak için harcayan programcılardan kaçınmaya çalışıyorum.)

@JoeWreschnig, seninle aynı fikirde olmama rağmen biraz kazma yaptım ve buldum: blog.ploeh.dk/2010/02/03/ServiceLocatorIsAnAntiPattern.aspx
Roy T.

2
Evet, ama bu adam DI kullanımı hakkında bir kitap satıyor; belli ki basit bir şey kullanmanı istemiyor, o zaman kitabını almayacaksın! (Ciddiyetle, Fowler'in orijinal DI / SL makalesi tam olarak bu konuyu ele aldı - martinfowler.com/articles/… - ve bu adamın blogu tartışmaya hiçbir şey

Keşke Martin Fowler'tan yanıt olarak gönderdiğin bağlantıyı işaretleyebilseydim (bu benim sorum olmasa da)
Roy T.

Yanıtlar:


6

Herkesin servis bulucuların kötü olduğunu kabul ettiğini düşünmüyorum. Servis Bulucuları, herkesin ihtiyaç duyduğu önemli işlevleri gerçek uygulamalarından ayırmanın bir yolunu sunar. Hizmet konum belirleyiciler ayrıca hizmetlerin çalışma zamanında değiştirilmesine de olanak tanır. Ayrıca servis bulucu etrafında her yerde geçmesi gereken doğru olduğunu sanmıyorum. Bence her yerden erişebilirsiniz. Globallerle bir oyun sınıfının kare başına yaklaşık bin kez geçmesi gerekirken (bu da kötü performansa neden olur).

Servis bulucu ile global olan bir sınıf arasındaki farkı biraz daha açık hale getirmek için aşağıdaki örneği göz önünde bulundurun:

Bir oyun yapıyorum ve global değişkenli bir gameA sınıfı nesneyi kullanıyorum: içerik yükleyici. Şimdi bir sonraki oyunumda gameA sınıfını kullanmak istemiyorum ama yeni bir gameB sınıfı oluşturuyorum. Şimdi gameA'nın küresellerini tekrar ekstra iş olan gameB'ye eklemeliyim. Ayrıca istediğim içerik yükleyiciyi yapılandırmak zorlaşıyor. Hem bilgisayarda hem de XBOX'da çalışan bir oyunum olduğunu varsayalım. PC'de 'dosya aç' iletişim kutusunu da açabilen bir içerik yükleyici istiyorum. XBOX üzerinde iken kesinlikle bunu istemiyorum. Bir yapılandırma dosyasına sahip olarak, oyunun yarısında bile içerik yükleyiciyi, gameA sınıfından başka bir yerden bile kolayca değiştirebilirim, sadece oyundaki küreselleri herkese açık hale getirmeden.

Şimdi bir servis bulucu kullandığımı düşünün. Her zaman kullanmaya devam edebilirim. Ve ne tür hizmetler olsa bile her zaman farklı olabilir. Ortak bir arayüze sahip oldukları sürece uygulamalarını bile önemsemeyeceğim de doğrudur. (Bunu bir gamA benzeri sınıfta da kullanabilsem de).

Her neyse, oyun hizmetlerini oldukça kullanışlı bulacağınızı düşünüyorum. Tanıdığım herkes kullanıyor. Size biraz daha yardımcı olmak için. Her zaman biraz daha az döküm yapabilmeniz için oyun hizmetleri etrafında küçük bir yardımcı sınıf oluşturdum: http://roy-t.nl/index.php/2010/08/25/xna-accessing-contentmanager -ve-graphicsdevice-her yerde-her zaman-the-gameservicecontainer / Ben oldukça kullanıyorum.


Yanıtınız için teşekkürler. Servis gerektiren bir sınıfta, genellikle ihtiyaç duyulduğunda servis için GameServices sınıfını mı istersiniz yoksa sınıfta bir üye değişkeni mi ve yalnızca kurucuda hizmet için istek mi yaratırsınız? Sanırım sorduğum şey ne kadar yavaş return (T)Instance.GetService(typeof(T));.
John Pollick

Ayrıca, GameServices sınıfının bu uygulaması hakkında ne düşünüyorsunuz ? Gereksiz singletonu kaldırdım çünkü soyutlamanın zaten sahip olmadığı hiçbir özelliği yoktu. Ayrıca, Serviceher yöntemin sonunda gereksiz soneki kaldırdım .
John Pollick

Ayrıca, hizmet AddServiceyönteminin bir tür almasının nedeninin hizmetin arabirimini belirtebileceğinizi düşünüyorum. Örneğin Services.AddService(typeof(IGraphicsDeviceManager), graphics);,. Daha sonra servisi alırken arayüzü tip olarak belirleyebilir ve seçtiğiniz alt sınıfa atabilirsiniz.
John Pollick

@JohnPollick, ilk soru için. Her zaman talep etmeye çalışıyorum (çünkü değişmiş olabilir) ama gerçekten her şeye ihtiyacım olursa her üye değişkenini oluşturuyorum. Benim için hiçbir zaman bir darboğaz olmasının dışında çok fazla performans istatistiğim yok. İkincisi, evet iyi görünüyor :). Ve üçüncüsü için. Tür argümanının nedeni de budur, ancak alınan değerleri asla küçümsemeyi alışkanlık haline getirmemelisiniz, çünkü bu sınıfları hizmet olarak takas etme yeteneğinizi yok eder. IGraphicsDeviceManger değil, bir MyGDM istemiyorsanız, muhtemelen yeni bir arabirim oluşturun.
Roy T.

1
Oh, senin de dökümünü görmedim. Tabii ki ilk döküm yaparsanız türü çıkarabilir :).
Roy T.

5

Öyleyse neden bu örnekleri sadece bir Singleton yapmıyoruz? Çünkü, Singletons kötü çünkü küresel bir duruma sahipler, test etmeyi önlüyorlar ve tasarımınızı daha kırılgan hale getiriyorlar.

Singletons genellikle çok sayıda yararlı özellik alır ve bunları, istemediğiniz çeşitli şeylerle birlikte istemediğiniz çeşitli şeyleri veren korkunç bir melezde bir araya getirir. ('Talep üzerine yarat' özellikleri miydi? Küresel kapsam? En az bir vakanın uygulanması? Birden çok vakanın yasaklanması?)

Hizmet konum belirleyicileri eşit olarak birçok kişiye karşı anti-desen olarak kabul edilir, çünkü sadece bir nesneye bağımlılığı geçmek yerine, bu sınıfı hizmetlerin geri kalanıyla birleştiren bir hizmet konum belirleyicisini (Oyun) geçirirsiniz.

Tamamen kuplajdan kaçınamazsınız. İşler başka şeyler kullanır ve bu olmadan programınız hiçbir şey yapmaz. Tek gerçek soru ne düzeyde bir soyutlama olduğudur.

Nesne yönelimli metinlerin çoğu Kompozisyon ve Toplama arasında bir ayrım yapar. Sahip olduğunuz ve bildiğiniz bir şey arasındaki kavramsal farkı bilmek önemlidir. Maalesef modern dillerin çoğunun burada belirgin bir ayrımı yoktur ve bir nesneye yapılan atıf, bunların her ikisi de anlamına gelebilir. (İronik olarak, çeşitli akıllı işaretçi türlerini kullanırsanız C ++ daha iyi bir iş çıkarır.)

Eğer hangi bir yolu olabilir kompozisyon yapmak ve kodunda net ve toplanan nesneler için hizmetlerini kullanarak gereğidir. Hizmetler, sahip olmadığınız, ancak kullanabileceğiniz şeylere erişim sağlamanın bir yoludur.

Öyleyse neden Hizmetler XNA ve oyun geliştirmede öneriliyor?

Oyun geliştirmede evrensel olarak önerildiklerini sanmıyorum.

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.