“빈”초록 / 수업을 가질 수 있습니까?


10

물론, 그런 식으로 디자인하는 것이 합리적인지 궁금합니다.

브레이크 아웃 클론을 만들고 클래스 디자인을하고있었습니다. 필자는 아니지만 C ++에서 배운 내용을 적용하기 위해 상속을 사용하고 싶었습니다. 나는 클래스 디자인에 대해 생각하고 다음과 같은 것을 생각해 냈습니다.

GameObject-> 기본 클래스 (x 및 y 오프셋과 같은 데이터 멤버와 SDL_Surface *

MovableObject 의 벡터로 구성됨 : GameObject-> 추상 클래스 + GameObject의 파생 클래스 (한 메서드 void move () = 0;)

NonMovableObject : GameObject-> 빈 클래스 ... 생성자 및 소멸자 이외의 메소드 또는 데이터 멤버가 없습니다 (적어도 지금은?).

나중에 Tileset : NonMovableObject와 같은 NonMovableObject에서 클래스를 파생시킬 계획이었습니다. "빈"추상 클래스 또는 빈 클래스가 자주 사용되는지 궁금합니다.이 작업을 수행하는 방식에 따라 분류를 위해 NonMovableObject 클래스를 작성하고 있습니다.

나는 브레이크 아웃 클론을 만들기 위해 일을 너무 많이 생각하고 있지만 내 게임에 집중하는 것이 아니라 상속을 사용하고 일종의 게임 프레임 워크를 디자인하는 데 더 중점을 둡니다.

답변:


2

C ++에는 다중 상속이 있으므로 빈 클래스를 사용하면 아무런 이점이 없습니다. 나중에 GameObject와 MovableObject에서 Ball을 상속 받게하려면 (예를 들어, GameObject의 배열을 유지하고 1 초마다 Tick 메소드를 호출하여 모두 움직이게하려면) 쉽게 할 수 있습니다.

그러나 그 상황에서 나는 개인적으로 " 상속 보다는 구성 (캡슐화)을 선호한다 "는 공리를 기억 하고 State 패턴을 보라고 제안합니다 . 나중에 각 오브젝트가 이동 상태를 갖도록하려면 GameObject에 전달하십시오. 예를 들면 : 공의 경우 DiagonalBouncingMovementState, 외륜의 경우 HoriazontalControlledMovementState, 벽돌의 경우 NoMovementState입니다.

1) 게임 오브젝트와 각 상태를 독립적으로 테스트 할 수 있기 때문에 (다시 권장하는) 단위 테스트 를 작성하는 것이 더 쉬워집니다 .

2) 벽돌에서 떨어지는 토큰이 있지만 그중 하나 를 변경 하여 클래스 상속의 복잡한 계층 구조 주위로 이동하는 대신 대각선으로 움직일 수 있다고 가정하면 하드 코딩 된 이동 상태를 변경할 수 있습니다. .

3) 가장 중요하게 : 게임 내 에서 해당 토큰을 기반으로 볼 및 / 또는 패들이 어떻게 움직이는 지 변경하려면 이동 상태를 계속 변경하면됩니다 (DiagonalMovementState는 DiagonalWithGravityMovementState가 됨).

이제는 상속보다 항상 캡슐화를 선호하는 이유를 보여주기 위해 상속이 항상 나쁘다는 것을 암시하지 않았습니다. 여전히 GameObject에서 각 유형의 오브젝트를 파생시키고 해당 클래스가 초기 이동 상태를 이해하도록 할 수 있습니다. C ++에는 인터페이스가 없기 때문에 추상 MovementState 클래스에서 각 이동 상태를 파생시키고 싶을 것입니다.

$ 0.02


8

Java에서 "빈"인터페이스는 마커 (예 : 직렬화 가능)로 사용됩니다. 런타임시 개체가 해당 인터페이스를 "구현"하는지 여부를 확인할 수 있기 때문입니다. 그러나 C ++에서는 나에게 무의미 해 보입니다.

IMO, 언어 기능은 도구로 간주되어야하며 의무가 아닌 특정 목표를 달성하는 데 도움이됩니다. 그냥 당신이 있기 때문에 할 수 당신이 의미하지 않는 기능을 사용 해야합니다 . 무의미한 상속으로 인해 프로그램이 개선되지는 않습니다.


3

당신은 그것을 너무 생각하지 않습니다; 당신은 생각하고 있고 좋습니다.

이미 언급했듯이 언어 기능 만 있기 때문에 언어 기능을 사용하지 마십시오. 학습 언어 기능 트레이드 오프는 좋은 디자인의 열쇠입니다.

분류를 위해 기본 클래스를 사용해서는 안됩니다. 검사 유형에 영향을 줄 수 있습니다. 나쁜 생각입니다.

객체의 계약을 정의하는 순수한 추상화를 작성하십시오. 객체의 계약은 외부 인터페이스입니다. 공용 인터페이스. 그것이하는 일.

참고 : 그것은이 이해하는 것이 중요 하지 가 무슨 데이터 x, y하지만 그것은 않습니다 move().

디자인에는 클래스가 GameObject있습니다. 기능이 아닌 데이터에 의존하고 있습니다. 그것은 느낌 귀하의 경우, 공통의 공유 데이터 것 같아 무엇을 공유하기 위해 상속을 사용하는 efficent하고 수정 x하고 y.

이것은 상속의 올바른 사용이 아닙니다. 상속은 가능한 가장 밀접한 형태의 커플 링이므로 항상 느슨한 커플 링을 위해 노력해야합니다.

본질적으로 NonMovableObject움직이지 않습니다. 그것 xy가장 확실하게 선언되어야한다 const. 본질적 MoveableObject으로 움직여야합니다. xy로 선언 할 수 없습니다 const. 따라서 이것은 동일한 데이터가 아니므로 공유 할 수 없습니다.

객체의 기능 또는 계약을 고려하십시오. 그들은 무엇을해야 합니까 ? 바로 잡으면 데이터가 올 것이다. 한 번에 하나의 대상에 대해 작업하십시오. 차례로 걱정하십시오. 좋은 디자인을 재사용 할 수 있습니다.

아마도 전혀 없을 것입니다 NonMovableObject. 메소드 GameObjectBase를 정의 하는 순수한 추상화 는 move()어떻습니까? 당신의 시스템은 GameObject어떤 것을 구현 move()하고 시스템은 움직일 필요가있는 것을 움직입니다.

이것은 시작에 불과합니다. 맛. 토끼 구멍이 훨씬 깊어집니다. 숟가락이 없다.


서로를 물려 MovableObject받거나 NonMovableObject물려받을 수는 없지만 둘 다 위치를 가지고 있습니다. 따라서, 그것들은 예를 들어 그 물체가 움직일 수 있는지 여부에 관계없이 물체를 향한 몬스터의 조준을 지시하고자하는 코드에 의해 소비 될 수 있어야한다.
supercat

2

ammoQ와 같은 C # 응용 프로그램이 있지만 C ++에서는 NonMovableObject 포인터 목록을 원할 경우 응용 프로그램 만 사용할 수 있습니다.

그러나 NonMoveableObject 포인터를 통해 객체를 파괴한다고 상상할 수 있습니다.이 경우 가상 소멸자가 필요하며 더 이상 빈 클래스가 아닙니다. :)


나는 그 경우에 대해서도 생각했지만 행동을 드러내지 않는 그러한 객체 목록으로 무엇을 할 수 있습니까? 아마도 실제 유형을 찾고 캐스트를 사용하여 사용 가능한 방법과 필드에 액세스 할 것입니다-분명히 코드 냄새.
user281377

예, 좋은 지적입니다.
tenpn

1

이를 볼 수있는 상황 중 하나는 강력한 유형의 컬렉션에 이기종 유형이 포함되도록하는 경우입니다. 나는 이것이 좋은 아이디어라고 말하지는 않습니다. 추상화가 약하거나 디자인이 좋지 않을 수 있지만 일어날 수 있습니다. 언급했듯이 물건을 분류하는 방법이며 유용하고 완벽하게 유효 할 수 있습니다.

예 : 고양이와 개를 담을 수있는 컬렉션이 필요합니다. 디자인에서는 공통점이 많으므로 기본 클래스 Mamal을 가지고 컬렉션에서이 유형을 사용하십시오 (예 : 목록). 문제 없다. 그런 다음 컬렉션에 개구리를 추가하고 싶지만 그들은 개구리가 아닙니다.이를 수행하는 한 가지 방법은 개구리와 포유류를 동물의 하위 클래스로 만드는 것입니다. 공통이므로 동물은 비어 있습니다. 그런 다음 Mamal 대신 Animal로 컬렉션을 입력하면 모든 것이 잘됩니다.

실제로는 빈 기반 클래스를 조만간 작성하더라도 일부 기능이 종료되지만 실제로 존재하는 경우가 있습니다.


그러나 질문해야 할 한 가지 질문은 유형에 공통점이 없으면 왜 동일한 콜렉션에 보유되는 것입니까? 컬렉션의 모든 항목에 대해 수행 할 수있는 작업이 없으므로 이러한 컬렉션을 갖는 목적을 상실합니다. 이제 방문자 설계 패턴 구현과 같이 논리를 단순화하기 위해 두 가지 모두에 추가 할 수있는 인공 작업이있을 수 있습니다.이 시점에서 다시 유용 해지지 만 이제는 공통점이 있습니다.
Jules
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.