1. 어떤 프로그램 만들기 전에는, 설계를 정확하게 하고 시작하자. 컴퓨터에겐 간단하겠지만, 내 작은 우동사리에게는 만만치 않다.
2. 항상 생각하면서 코드를 고치자..
텍스트 게임을 만드는 것을 만만히 보았다. 그냥 대충 클래스 몇 개 만들고 하면 되지 않을까 하였다.
그리고 그것은 오산이었다. 내 머리는 그리 똑똑하지 않았다.
몇 개 클래스 안되는데 사실, 캐릭터 클래스랑, 배틀 전투 클래스랑 뭐 이정도인데, 예외 처리 하고 루프 몇 개 돌리고 하니까 머릿속이 복잡해 지는 것이다.
이 때 깨달았다. 왜 팀장님이 프로젝트 시작하시기 전에 다이어그램으로 전체 설계 도면부터 만들고 공유하시면서 시작하셨는지.
여기서 1번을 배웠다. 어떤 프로그램 만들던간에, 설계를 정확하게 하고 시작하자. 간단할 것 같아서 청순한 백지의 마음과 머리로 시작하지는 말자. 컴퓨터에겐 간단하겠지만, 내 작은 우동사리에게는 만만치 않다.
그리고 두 번째는 머리 비우고 코드 고치지 말자.
처음에 monster
변수를 late final Monster monster;
이런 식으로 해 두었다. 그런데 게임 도중에 내가 맞서 싸우는 monster
가 계속 바뀌는데, late final
이렇게 해 두니 안되는 것이다.
monster
는 내가 전투를 진행하는 동안 계속 업데이트 되어야 하는 아이이므로, Monster?
이렇게 Nullable 타입으로 선언하는 것이 더 적절하다.
class Game {
final Character character;
List<Monster> monsters;
Monster? monster; // nullable로 수정하여 초기화 및 재할당 가능
그래서 Monster? monster;
로 바꾸니 이제 monster
를 조건으로 걸어두었던 if, while문이 전부 에러를 내뱉기 시작하였다.
"nullable 한 애들을!!! 조건으로 쓰면 어떡하니????" 라고 내게 아주 스트레스를 주는 그런 에러 문구를,, 터미널에 쏟아냈다...
monster
를 nullable로 선언해서 Monster?
타입으로 변경했으므로, 해당 변수에 접근할 때마다 null 안전성을 보장하기 위해 null 체크를 해 주어야 한다. 다음과 같은 방식으로 체크하면 된다.
- monster 옆에 강제로 느낌표(!)를 붙여서 강제로 non-null로 처리한다.
- monster != null로 null 확인 후 접근한다.
둘 중의 하나만 하면 되고, 나는 느낌표만 붙여주기로 하였다.
상처받은 마음을 뒤로 한 채, monster.isAlive()
이런 것들을 모두 monster!.isAlive()
이렇게 고쳐나갔다.
그러다가 if(!monster!.isAlive()) { blah blah ~}
이런 부분을 발견했고, 나는 아무 생각 없이
// 몬스터가 죽었는지 확인 후 다음 전투 여부 결정
if (!monster!.isAlive()) {
print('${monster!.name}을(를) 물리쳤습니다!');
monsters.remove(monster);
monsterKillCount++;
엥? 왜 느낌표를 내가 앞에도 넣었지? 오타인가? 하고 맨 앞 느낌표를 지웠다. if(monster!.isAlive()) { blah blah ~}
이렇게 바꾸었다. 그리고 에러가 시작되었다.
그렇게 아무 생각없이 코드를 고치면 안되는 것이었다.
항상 생각을 하고 코드를 고치자...
저렇게 하니까 몬스터들이 막 싸우지도 않고 지들이 다 물리쳐졌다는겁니다. 말도 안돼... 저거 아무 생각 없이 느낌표 지웠다가, 실수 다시 찾아내기까지 한 십오분 걸린 것 같다. 하지만 체감상 45분 느낌이었다.