정적 클래스는 올바른 위치에서 사용되는 한 괜찮습니다.
즉, '리프'메서드 인 메서드 (상태를 수정하지 않고 단순히 입력을 어떻게 든 변형). 이에 대한 좋은 예는 Path.Combine과 같은 것입니다. 이러한 종류의 것들은 유용하고 간결한 구문을 만듭니다.
문제 내가 정적에있는 수많은 있습니다 :
첫째, 정적 클래스가있는 경우 종속성이 숨겨집니다. 다음을 고려하세요:
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를 보면 생성자를 보면 어떤 초기화 단계를 수행해야하는지 알 수 없습니다. 클래스를 조사하여 종속성을 찾고 올바른 순서로 초기화해야합니다. 이 경우 실행하기 전에 ResourceLoader를 초기화해야합니다. 이제이 의존성 악몽을 확장하면 어떤 일이 일어날 지 짐작할 수 있습니다. 명시적인 초기화 순서가없는 코드를 유지하려고한다고 상상해보십시오. 인스턴스를 사용한 종속성 주입과 대조하십시오.이 경우 종속성이 충족 되지 않으면 코드가 컴파일 되지 않습니다!
또한 상태를 수정하는 정적을 사용하는 경우 카드의 집과 같습니다. 누가 무엇에 접근 할 수 있는지 결코 알 수 없으며 디자인은 스파게티 괴물과 비슷합니다.
마지막으로, 정적을 사용하는 것은 프로그램을 특정 구현에 연결하는 것입니다. 정적 코드는 테스트 가능성을위한 디자인의 반대입니다. 통계로 가득 찬 코드를 테스트하는 것은 악몽입니다. 정적 호출을 테스트 이중으로 바꿀 수는 없으므로 (정적 유형을 모방하도록 특별히 설계된 테스트 프레임 워크를 사용하지 않는 한) 정적 시스템은이를 사용하는 모든 것을 즉시 통합 테스트로 만듭니다.
요컨대, 정적은 어떤 것에는 괜찮으며 작은 도구 또는 일회용 코드에는 사용을 권장하지 않습니다. 그러나 그 이상으로 유지 보수성, 좋은 디자인 및 테스트 용이성에 대한 피비린내 나는 악몽입니다.
다음은 문제에 대한 좋은 기사입니다. http://gamearchitect.net/2008/09/13/an-anatomy-of-despair-managers-and-contexts/