내가 아는 많은 부지런한 소프트웨어 개발자들은 개체에 대한 참조를 처리하기 위해 제어 및 종속성 주입의 반전으로 이동 하고 있습니다. 플래시 게임의 관점에서봤을 때 AAA 스튜디오의 모든 기능을 알지 못하므로 소매 게임 세계에서 사용됩니까?
내가 아는 많은 부지런한 소프트웨어 개발자들은 개체에 대한 참조를 처리하기 위해 제어 및 종속성 주입의 반전으로 이동 하고 있습니다. 플래시 게임의 관점에서봤을 때 AAA 스튜디오의 모든 기능을 알지 못하므로 소매 게임 세계에서 사용됩니까?
답변:
당신은 그것을 '부지런한 소프트웨어 개발'이라고 부릅니다. 제어의 역전이 나쁘다는 것은 아닙니다. 사실, 기본 정의는 훌륭합니다. 그러나 모든 것을 달성하기 위해 노력하는 전체 프레임 워크와 방법의 확산은 특히 사람들이 쓰레기를 버리는 방식과 결합되어 미쳤습니다. 상호 교환이 불가능한 99 %의 교체 가능한 구성 요소를 주입 할 수 있도록 완벽하고 깔끔한 인터페이스. 그것은 Java 엔터프라이즈 환경에서만 시작될 수있는 종류의 일이며 다른 곳에서 발판이 많지 않아서 기쁩니다.
구성 요소를 서로 바꾸지 않더라도 모의 객체 등과 분리하여 테스트 할 수 있기를 원한다는 주장이 종종 있습니다. 그러나 나는 그것을 더 잘 테스트하기 위해 팽만감과 인터페이스를 복잡하게 할 가치가 있다는 주장을 결코 사지 않을 것이라고 두려워한다. 테스트는 한 가지만 증명합니다. 테스트가 작동한다는 것입니다. 반면에 깨끗하고 최소한의 인터페이스는 코드 작동 을 입증 하는 데 먼 길을갑니다 .
그래서 짧은 대답 : 예, 그러나 당신이 생각하는 방식이 아닙니다. 때때로, 상호 교환 가능한 행동이 필요할 때, 새로운 객체의 행동의 일부를 지시하는 생성자에게 객체를 전달할 수 있습니다. 그게 다야.
전략 패턴 , 구성 , 의존성 주입 은 모두 매우 밀접한 관련이 있습니다.
전략 패턴은 Dependency Injection의 한 형태이므로 Unity와 같은 엔진을 살펴보면이 원칙을 완전히 기반으로합니다. 구성 요소 (전략 패턴) 사용은 전체 엔진에 깊이 포함되어 있습니다.
구성 요소 재사용을 제외하고 주요 이점 중 하나는 끔찍한 딥 클래스 계층 구조를 피하는 것입니다.
Mick West 의 기사는 Neversoft 의 Tony Hawk 시리즈 게임에 이러한 유형의 시스템을 어떻게 도입했는지에 대해 설명합니다 .
상당히 최근까지 게임 프로그래머는 게임 개체를 나타 내기 위해 지속적으로 딥 클래스 계층 구조를 사용했습니다. 조류는 이러한 딥 계층 구조의 사용에서 구성 요소의 집합으로 게임 개체 개체를 구성하는 다양한 방법으로 전환하기 시작했습니다 ...
IoC (Inversion of Control) 패턴에 대해 많은 혼동이있는 것 같습니다. 많은 사람들이 전략 패턴이나 구성 요소 모델을 사용했지만이를 비교한다고해서 실제로 IoC가 무엇인지 파악할 수는 없습니다. IoC는 실제로 의존성을 얻는 방법에 관한 것입니다. 예를 들어 보겠습니다.
class Game {
void Load() {
this.Sprite.Load(); // loads resource for drawing later
}
}
class Sprite {
void Load() {
FileReader reader = new FileReader("path/to/resource.gif");
// load image from file
}
}
위에서 Sprite.Load
는에 의존하는 것이 분명합니다 FileReader
. 분석법을 테스트하려면 다음이 필요합니다.
처음 두 개는 분명하지만 오류 처리가 예상대로 작동하도록하려면 실제로 # 3도 필요합니다. 두 경우 모두 이제 디스크로 이동해야하기 때문에 테스트 속도가 상당히 느려졌으며 테스트 환경이 더 복잡해졌습니다.
IoC의 목표는 동작 사용을 구성에서 분리하는 것입니다. 이것이 전략 패턴과 어떻게 다른지 주목하십시오. 전략 패턴의 목표는 재사용 가능한 행동 덩어리를 캡슐화하여 나중에 쉽게 확장 할 수 있도록하는 것입니다. 전략이 어떻게 구성되는지에 대해서는 말할 것도 없습니다.
Sprite.Load
위 의 방법 을 다시 작성하면 다음과 같이 끝날 것입니다.
class Sprite {
void Load(IReader reader) {
// load image through reader
}
}
이제 독자의 구성을 사용에서 분리했습니다. 따라서 테스트 중에 테스트 리더를 교체 할 수 있습니다. 이는 테스트 환경에 더 이상 파일 시스템, 테스트 파일이 필요하지 않으며 오류 이벤트를 쉽게 시뮬레이션 할 수 있음을 의미합니다.
다시 쓰기에서 두 가지 작업을 수행했습니다. IReader
전략을 구현 하는 인터페이스 를 만들었습니다. 즉, 전략 패턴을 구현했습니다. 또한 올바른 독자를 만드는 책임을 다른 수업으로 옮겼습니다.
위의 내용을 설명하기 위해 새로운 패턴 이름이 필요하지 않을 수도 있습니다. 전략과 팩토리 패턴 (IoC 컨테이너의 경우)이 혼합되어 있습니다. 즉, 실제 문제를 해결한다는 것이 확실하기 때문에 사람들 이이 패턴에 반대하는 근거가 무엇인지 확실하지 않으며 확실히 Java와 관련이 있는지 분명하지 않습니다.
나는 그것이 많은 도구 중 하나라고 말하고 때로는 사용됩니다. tenpn이 말했듯이 vtable을 도입하는 모든 메소드 (및 일반적으로 추가 간접 처리)는 성능 저하가 발생할 수 있지만 이는 저수준 코드에 대해서만 걱정해야 할 사항입니다. 실제로 문제가되지 않는 고급 구조 코드의 경우 IoC는 긍정적 인 이점을 가질 수 있습니다. 클래스 간의 종속성을 줄이고 코드를 더 유연하게 만드는 것.
Kylotan에 동의해야합니다. "종속성 주입 (dependency injection)"은 못생긴 Java 개념 결함에 대한 못생긴 Java 솔루션이며, 다른 언어로 다른 사람이 그것을보고있는 유일한 이유는 Java가 실제로는 말아야 할 때 많은 사람들에게 첫 언어가되기 때문 입니다.
반면에 제어 반전은 오랫동안 사용되어 왔으며 올바르게 수행하면 매우 유용합니다. (Java / Dependency Injection 방식은 아닙니다.) 사실, 제정신의 프로그래밍 언어로 작업한다면 항상 그렇게 할 것입니다. 모두가 윙윙 거리는이 "IOC"전체를 처음 읽었을 때, 나는 완전히 압도당했습니다. Inversion of Control은 그 동작을 커스터마이즈하기 위해 함수 포인터 (또는 메소드 포인터)를 루틴이나 객체에 전달하는 것 이상입니다.
이것은 1950 년대부터 존재 해 온 아이디어입니다. C 표준 라이브러리 (qsort가 떠오를 것입니다)에 있으며 Delphi 및 .NET (이벤트 핸들러 / 대의원) 의 모든 곳에 있습니다. 이전 코드는 기존 코드를 다시 컴파일 할 필요없이 새 코드를 호출 할 수있게 해주 며 게임 엔진에서 항상 사용됩니다.
나는 전문 게임 개발자가 아니며 C ++에서 IoC를 한 번만 구현하려고 시도했기 때문에 추측하고 있습니다.
그러나 나는 게임 개발자가 다음을 의미하기 때문에 IoC에 대해 의심 스러울 것이라고 생각합니다.
1 / 많은 인터페이스와 많은 작은 클래스 디자인
2 / 거의 모든 함수 호출이 최근에 바인딩됩니다.
이제 우연의 일치 일지 모르지만 둘 다 IoC가 널리 보급 된 Java보다 C + + (게임에서 널리 사용되지는 않습니까?)의 성능에 대해 조금 더 복잡하거나 문제가되는 경향이 있습니다. 비교적 쉬운 작업을 수행하여 사람들이 더 안전한 객체 계층 구조를 설계하도록 돕고 일부는 Java로 응용 프로그램을 작성하여 XML로 응용 프로그램을 작성할 수 있다고 믿었 기 때문에 또 다른 논쟁입니다 : P)
의견이 전혀 이해가되지 않으면 의견에 관심이 있습니다.)