Statik sınıflar, doğru yerlerde kullanıldıkları sürece iyidir.
Yani: 'yaprak' yöntemler olan yöntemler (durumu değiştirmezler, sadece girdiyi bir şekilde dönüştürürler). Bunun güzel örnekleri Path.Combine gibi şeylerdir. Bu tür şeyler yararlıdır ve daha ayrıntılı sözdizimi sağlar.
Sorunlar Ben statiği ile olan çoktur:
İlk olarak, statik sınıflarınız varsa, bağımlılıklar gizlidir. Aşağıdakileri göz önünde bulundur:
public static class ResourceLoader
{
public static void Init(string _rootPath) { ... etc. }
public static void GetResource(string _resourceName) { ... etc. }
public static void Quit() { ... etc. }
}
public static class TextureManager
{
private static Dictionary<string, Texture> m_textures;
public static Init(IEnumerable<GraphicsFormat> _formats)
{
m_textures = new Dictionary<string, Texture>();
foreach(var graphicsFormat in _formats)
{
// do something to create loading classes for all
// supported formats or some other contrived example!
}
}
public static Texture GetTexture(string _path)
{
if(m_textures.ContainsKey(_path))
return m_textures[_path];
// How do we know that ResourceLoader is valid at this point?
var texture = ResourceLoader.LoadResource(_path);
m_textures.Add(_path, texture);
return texture;
}
public static Quit() { ... cleanup code }
}
TextureManager'a baktığınızda, bir kurucuya bakarak hangi başlatma adımlarının gerçekleştirilmesi gerektiğini söyleyemezsiniz. Bağımlılıklarını bulmak ve şeyleri doğru sırada başlatmak için sınıfa girmelisiniz. Bu durumda, ResourceLoader'ın çalıştırılmadan önce başlatılması gerekir. Şimdi bu bağımlılık kabusunu büyütün ve muhtemelen ne olacağını tahmin edebilirsiniz. Açık bir başlatma sırasının olmadığı bir yerde kodu korumaya çalıştığınızı hayal edin. Bunu örneklerle bağımlılık enjeksiyonu ile karşılaştırın - bu durumda , bağımlılıklar yerine getirilmezse kod derlenmez !
Dahası, durumu değiştiren statiği kullanırsanız, bu bir kartlar evi gibidir. Kimin neye erişimi olduğunu asla bilemezsiniz ve tasarım bir spagetti canavarına benzeme eğilimindedir.
Son olarak ve en önemlisi, statiği kullanmak bir programı belirli bir uygulamaya bağlar. Statik kod, test edilebilirlik için tasarım yapmanın antitezidir. Statikle dolu kodu test etmek bir kabustur. Statik bir çağrı asla bir çift test için değiştirilemez (özellikle statik türleri alay etmek için tasarlanmış test çerçevelerini kullanmadığınız sürece), bu nedenle statik bir sistem, onu kullanan her şeyin anında bir entegrasyon testi olmasına neden olur.
Kısacası, statik bazı şeyler için iyidir ve küçük araçlar veya atılan kodlar için kullanımlarını engellemem. Ancak bunun ötesinde, bakım kolaylığı, iyi tasarım ve test kolaylığı için kanlı bir kabustur.
İşte problemlerle ilgili güzel bir makale: http://gamearchitect.net/2008/09/13/an-anatomy-of-despair-managers-and-contexts/