2021 04 08
2021-04-08¶
체스 피드백¶
1. ChessService의 메서드들의 synchronized 예약어를 삭제했어요.
synchronized 예약어는 멀티 스레드 환경에서 스레드간 동기화를 지원해요.
여러 개의 스레드가 한 개의 자원을 사용하고자 할 때, 현재 데이터를 사용하는 스레드를 제외하고는 나머지 스레드들의 접근을 막아줘요.
제가 처음 synchronized를 도입했던 이유는, ChessService에서 domain 객체를 인스턴스 변수로 가졌기 때문이에요.
멀티 쓰레드 환경에서 해당 domain 객체가 의도대로 동작하지 않는 것을 방지하고자 synchronized 예약어를 붙였어요.
하지만 리팩토링을 통해 ChessService가 domain 객체를 갖지 않도록 stateless하게 변환을 했어요.
따라서 다양한 스레드에서 ChessService 내의 메서드를 실행해도, race-condition이 발생할 인스턴스 변수가 없어요.
덕분에 stateless하게 구현하는 것의 장점을 느껴볼 수 있었습니다 :)
따라서 synchronized 예약어를 삭제했어요!
2. 진행 중인 게임이 있는 경우, 새로운 게임 요청을 받는다면?
DB에 완료되지 않은 게임 정보가 저장되어 있는데, 새로운 게임을 실행하도록 요청을 받는다면,
지금 까지는 그냥 기존 데이터를 모두 삭제하고 새로운 게임을 만들어 반환헀어요.
해당 방식을 다음과 같이 개선했어요.
만약 DB에 완료되지 않은 게임이 있는 상태에서 새로운 게임 시작 요청을 받으면,
사용자 UI에서 기존 게임을 삭제하고 새로운 게임을 시작하겠냐고 물어보게 만들었어요.
사용자가 새로운 게임을 시작하겠다라고 답변하면, forceNewGame 이라는 API로 요청을 보내 기존 게임 정보를 삭제하고 새로운 게임을 만들도록 했습니다.
3. 미립이 남겨주신 피드백들을 반영했어요!
제 개인적인 실수들을 고쳤고, 메서드 이름에 알맞게 동작하도록 리팩토링 진행했습니다!
자세한 구현은 대댓글로 남겨놨어요!
4. DB에 필요한 정보를 String으로 넣는다면?
Qs.
추가로 지금 데이터베이스에 기물정보를 한 컬럼에 모두 넣어놓고 파싱해서 사용하고 있어요.
RDB 는 말그대로 관계형(Relational)으로 구성되는게 좋다고 생각해요.
지금 단계에서 수정을 할 필요는 없다고 생각하지만 조엘도 한 번 가볍게 고민해보면 좋을 것 같아요.
Ans.
해당 방식으로 구현한 경우, 단점들에 대해 조사해봤어요.
다른 크루도 비슷한 피드백을 받아서, 이를 참고했어요.
참고: https://github.com/woowacourse/java-chess/pull/260
-
데이터에 대한 쿼리가 불가능해요 각 기물에 대한 정보만 빼오고 싶은 경우도 분명히 있을 거에요. 하지만 해당 방식은 이를 포기했어요. 이는 확장성이 떨어지는 방식이라고 판단이 되어요.
-
DB 마이그레이션이 어렵다 기존 데이터를 새로운 DB에 저장을 하려고 하는 경우, 그저 텍스트만 있는 현재 DB는 변화에 유연하지 못할 것 같아요.