목차
DataHandler, 상속 설계의 중요성
야근과.. 주말 이틀 잔업이 확정되었다.
DataHandler
상황
monsterAI 컴포넌트를 내가 맡고, 팀원이 Data나 Condition 같은 컴포넌트들을 구현함.
추후에 코드리뷰를 통해 서로의 코드를 이해하고, 컴포넌트들을 합치는 monster 클래스를 작성하자는 계획을 세웠기 때문.
그러나 보스몬스터를 구현하는데 급급해서 노말 몬스터와 분리하여 구현할 상속 관계를 간과하였음.
Condition 컴포넌트의 경우, 보스몬스터와 노말 몬스터가 동일하게 갖게 될 컴포넌트인데, 메인에서 끌고와야할 data가 BossMonsterModel인지 NormalMonsterModel인지 확인할 방법이 필요했음.
(제너릭을 사용하는 등의 방법이 떠올랐으나 여전히 유지보수성이 극악일 것이라 예상되었음.)
시도
BossMonsterModel과 NormalMonsterModel은 상속 관계를 가질 수 없음.
기획테이블에서 json data를 변환하며 클래스를 자동생성 및 리스트를 생성하는 툴을 사용 중인데
현재 이 툴에서 클래스를 생성할때 커스터마이징을 할 수 없는 상황이었기 때문.
따라서 상속을 포함해 parital, interface, 등등의 아이디어들이 있었으나
추후 기획테이블과의 연동을 위해서라면 다른 방법을 찾아야했음.
해결 방법
기획테이블과 연동하며 자동 생성하는 클래스와 데이터와는 별개로 내가 원하는 Data Model을 유지하기 위해서
DataHandler를 구현하기로함.
DataHandler는 다음과 같이 구현하였음.
public class MonsterDataHandler
{
/// <summary>
/// 기획테이블에서 가져온 데이터를 현재 데이터 형식에 맞게 깊은 복사하여 맵핑
/// </summary>
public BossMonsterModel MapFromTableData(MonsterTableData tableData)
{
//todo think. deepcopy를 굳이 해줘야하나?
int[] specialSkillIds = new int[tableData.specialSkillIds.Length];
Array.Copy(tableData.specialSkillIds, specialSkillIds, specialSkillIds.Length);
int[] commonSkillIds = new int[tableData.commonSkillIds.Length];
Array.Copy(tableData.commonSkillIds, commonSkillIds, commonSkillIds.Length);
BossMonsterModel newBossMonsterModel = new BossMonsterModel(
tableData.monsterId, tableData.monsterName, tableData.health,
tableData.chaseSpeed, tableData.attackRange, tableData.attackCooldown,
specialSkillIds,
commonSkillIds);
return newBossMonsterModel;
}
}
여기에서 MonsterTable은 기획테이블을 기반으로 자동생성된 클래스.
현재는 보스몬스터만 구현하므로 return값이 보스몬스터모델인 메서드만 생성하였으나,
추후 노멀몬스터를 구현하게 된다면 적당한 메소드명 변경과 함께 return 값이 노멀몬스터모델인 메서드를 추가해야한다.
장점
- 시스템으로부터 독립:
- 자동 생성 시스템의 제약사항(상속, 인터페이스 구현 불가 등)에 얽매이지 않고 원하는 객체 지향적 설계를 자유롭게 적용 가능
- 데이터의 불변성과 안정성 확보:
- DataHandler 내부에서 깊은 복사하여 DataTableManager에 저장된 원본 데이터는 불변성을 유지할 수 있음.
- 각 몬스터 객체가 독립적인 사본을 갖게 되므로 데이터 오염 문제를 방지하여 코드의 신뢰성과 무결성을 향상시킴.
- 유지보수성과 확장성
- DataHandler에서 데이터 변환이라는 단일 책임을 맡게 되어 단일 책임 원칙을 유지.
- 이로인해 기획 테이블의 스키마가 변경되더라도 데이터 변환 로직이 DataHandler에 집중되어있어 수정이 용이함.
- 새로운 몬스터 타입 추가 시 매핑메서드만 추가하면 되므로 확장이 쉬워짐. (기존 코드를 수정하지 않아도 되는 개방-폐쇄 원칙을 유지함)
- 협업 능률 향상
- 기획 테이블의 변동과 무관하게 몬스터 구현을 진행할 수 있다.
- 구현 대기 시간 동안 기획테이블에 미리 데이터를 추가하여 작업할 수 있음. (DataHandler가 필요한 데이터만 가공해주므로)
- 기획 테이블의 변동과 무관하게 몬스터 구현을 진행할 수 있다.
느낀점
상속 설계의 중요성
위의 트러블슈팅을 보면 구조를 안잡고 시작했냐??라고 할수도 있지만..
오전에 구조를 잡았었다. 심지어 어제 짠 것을 수정하는 작업이었음.
하지만 1차 프로토타입에 맞춰서 보스몬스터에만 집중하느라 상속 관계를 놓침.
사실은 알고 있었음... 상속 관계도 짜야한다는 걸..
근데 플레이어측은 이미 벽점프를 구현하는 상황에서 몬스터 팀 또한 빨리 개발 시작해야한다는 압박감이 있었던 것 같다.
또한 몬스터의 메인 구조(컴포넌트 포함)는 둘이서 추후 나눠서 작업을 해야하므로 완전히 코드를 이해할 수 있는 페어프로그래밍을 진행했어야했는데,
피로도가 높은 페어 프로그래밍의 특징 + 내 체력의 고갈로 인해 지구력이 떨어져서 오후에는 각자 코딩한 후 만나겠다는 판단을 내렸던 것 같음.
이렇게 해야할 작업을 하지 않고 넘어가게 된 것, 효율적이지 못한 작업 과정을 선택하게 된 것은 내 체력 문제도 있는 것 같다.
부족한 에너지 때문에 판단력이 흐려진 것....
수영 다시 끊어야하나... 아무튼 운동을 해야겠다는 생각이 들었음.
같이 열심히 고민했던 팀원 분에게 죄송한 마음...
저녁 스크럼 때 우리팀 이런거 했어요!! 하고 자랑하고 싶었는데 그게 안되서 조금 속상했던 것 같다.
내일 학습 할 것은 무엇인지
일단 상속 문제를 해결하느라 마주하게 된 Data는 해결이 되었다.
이제 진짜 몬스터 구조를 짜게 될 것 같다.
컴포넌트들 먼저 해결한 뒤, 메인 클래스인 BossMonster 클래스를 완료하는 순서로 진행하게 될 것 같다.
또한 팀원에게 코드리뷰를 하기 위해서 클래스다이어그램 업데이트 또한 필요하다.
'부트캠프 > 본캠프' 카테고리의 다른 글
| [내일배움캠프_2025SEP14] BT 구현 시작, 코드 리뷰 가능할까...? (0) | 2025.09.14 |
|---|---|
| [내일배움캠프_2025SEP13]리팩토링 (0) | 2025.09.13 |
| [내일배움캠프_2025SEP11] Behavior Tree (0) | 2025.09.11 |
| [내일배움캠프_2025SEP10] 프레임워크 몹 프로그래밍, 최적화 학습 (0) | 2025.09.10 |
| [내일배움캠프_2025SEP09] Cry4Code 팀 결성! (0) | 2025.09.09 |