BobDalgleish는 이 (반) 패턴을 " 트램프 데이터 " 라고 언급 했습니다 .
필자의 경험에 따르면 과도한 트램프 데이터의 가장 일반적인 원인은 객체 또는 데이터 구조에 실제로 캡슐화되어야하는 연결된 상태 변수가 많이 있기 때문입니다. 때로는 데이터를 올바르게 구성하기 위해 많은 개체를 중첩해야 할 수도 있습니다.
간단한 예를 들어, 같은 특성을 가진 사용자 정의 플레이어 캐릭터가있는 게임을 고려 playerName
, playerEyeColor
등등합니다. 물론 플레이어는 게임 맵에서 물리적 위치와 현재 및 최대 건강 수준 등과 같은 다양한 다른 속성을 가지고 있습니다.
이러한 게임의 첫 번째 반복에서는 이러한 모든 속성을 전역 변수로 만드는 것이 합리적 일 수 있습니다. 결국 플레이어는 하나 뿐이며 게임의 거의 모든 것이 플레이어와 관련이 있습니다. 따라서 전역 상태에는 다음과 같은 변수가 포함될 수 있습니다.
playerName = "Bob"
playerEyeColor = GREEN
playerXPosition = -8
playerYPosition = 136
playerHealth = 100
playerMaxHealth = 100
그러나 언젠가는 게임에 멀티 플레이어 모드를 추가하고 싶기 때문에이 디자인을 변경해야 할 수도 있습니다. 첫 번째 시도로 모든 변수를 로컬로 만들어 필요한 함수에 전달할 수 있습니다. 그러나 게임의 특정 액션에 다음과 같은 함수 호출 체인이 포함될 수 있습니다.
mainGameLoop()
-> processInputEvent()
-> doPlayerAction()
-> movePlayer()
-> checkCollision()
-> interactWithNPC()
-> interactWithShopkeeper()
...이 interactWithShopkeeper()
기능은 상점 주인에게 플레이어 이름을 지정하므로 이제 모든 기능을 playerName
통해 갑자기 부정기 데이터 를 전달해야 합니다. 물론 상점 주인이 파란 눈을 가진 플레이어가 순진하고 더 높은 가격을 책정한다고 생각 하면 전체 기능 체인 등 을 통과해야합니다 .playerEyeColor
적절한 솔루션이 경우, 이름을 캡슐화하는 플레이어 객체를 정의하는 물론, 눈 색깔, 위치, 건강과 플레이어 캐릭터의 다른 특성이다. 그렇게하면 플레이어와 관련된 모든 기능에 단일 객체를 전달하기 만하면됩니다.
또한, 위의 기능 중 일부는 자연스럽게 해당 플레이어 객체의 메소드로 만들어 질 수 있으며,이를 통해 플레이어의 속성에 자동으로 액세스 할 수 있습니다. 어쨌든 이것은 객체의 메소드를 호출하면 객체 인스턴스를 숨겨진 매개 변수로 메소드에 효과적으로 전달하기 때문에 구문상의 설탕 일뿐입니다. 그러나 올바르게 사용하면 코드가 더 명확하고 자연스럽게 보입니다.
물론, 전형적인 게임은 단순한 플레이어보다 훨씬 "전세계적인"상태를 가질 것입니다. 예를 들어, 게임이 진행되는지도와 플레이어가 아닌 캐릭터 목록,지도 위에 놓인 아이템 등이있을 것입니다. 주위의 모든 것을 tramp 객체로 전달할 수도 있지만 메소드 인수를 다시 혼란스럽게 만듭니다.
대신, 해결책은 오브젝트가 영구적 또는 임시 관계가있는 다른 오브젝트에 대한 참조를 저장하도록하는 것입니다. 따라서, 예를 들어, 플레이어 객체는 같은 방법 있도록 현재 수준 /지도에 대한 참조를 가질 것 "게임 세계"개체에 대한 참조를 저장해야합니다 아마 (아마 어떤 NPC가 너무 객체) player.moveTo(x, y)
을 필요로하지 않는다 맵을 매개 변수로 명시 적으로 제공해야합니다.
마찬가지로 플레이어 캐릭터가 애완견을 따라 다니는 경우 개를 설명하는 모든 상태 변수를 자연스럽게 단일 개체로 그룹화하고 플레이어 개체에 개에 대한 참조를 제공합니다 (플레이어가 예를 들어, 개를 이름으로 부르고 그 반대의 경우도 있습니다 (개가 플레이어의 위치를 알 수 있도록). 물론 플레이어와 개 개체를보다 일반적인 "actor"개체의 하위 클래스로 만들면지도에서 두 코드를 이동하는 데 동일한 코드를 재사용 할 수 있습니다.
추신. 게임을 예로 사용했지만 이러한 문제가 발생하는 다른 종류의 프로그램이 있습니다. 그러나 내 경험상 근본적인 문제는 항상 같은 경향이 있습니다. 하나 이상의 상호 연결된 객체로 함께 묶고 싶은 별도의 변수 (로컬 또는 글로벌 여부)가 있습니다. 함수에 침입하는 "트램프 데이터"가 수치 시뮬레이션에서 "글로벌"옵션 설정 또는 캐시 된 데이터베이스 쿼리 또는 상태 벡터로 구성되어 있는지 여부에 관계없이 솔루션은 데이터가 속하는 자연 컨텍스트 를 식별하고 이를 객체로 만드는 것입니다. (또는 선택한 언어에서 가장 가까운 것).