질문, 피드백 등 모든 댓글 환영합니다
KUIT은 건국대학교 교내 개발동아리로 2023년 1기로 시작해 24년 현재 4기가 진행 중입니다. Web / Server / Android / iOS / PM / Designer 직군이 있으며, 학기 중에는 디자이너를 제외한 각 분야 파트장들이 제공하는 강의와 미션을 기반으로 스터디를 진행하고, 방학 중에는 각 직군이 모여 프로젝트를 진행하는 것으로 한 기수의 활동이 마무리됩니다.
KUIT 1기 서버 부원을 시작으로 2기 서버 튜터, 4기에는 서버 파트장을 맡게 되었습니다. 파트장을 하며 부원들께 전달한 강의와 미션 준비 과정에 대한 회고를 작성하려 합니다.
두 번째로 2주 차에 대한 강의와 미션에 대한 회고를 작성합니다.
KUIT 4th Server 파트의 커리큘럼은 아래와 같습니다.(블로그 작성 시점, 현재 4~5주 차 진행중)
총 10주 차의 커리큘럼 중 제가 맡은 부분은 1~3주 차입니다.
1주 차 강의는 객체 지향과 테스트에 관한 내용을 다뤘고 미션으로 사다리타기 게임 구현이 제공되었습니다. 2주 차 강의와 미션은 1주 차에서 이어집니다.
2주 차 강의는 미션에 대한 리팩토링 과정을 라이브 코딩으로 제공합니다.
강의 진행 코드는 https://github.com/Konkuk-KUIT/KUIT4_Server-Ladder/tree/1week-basic 에서 시작합니다.
1주 차에는 객체 지향에 관한 내용을 학습하고 소트웍스 앤솔러지의 객체 지향 개발 생활 체조 원칙을 참고하여 사다리타기 게임을 구현했었습니다. 예전에 저 또한 그랬듯이, 많은 부원들이 객체 지향적으로 깊게 고민하여 코드를 작성하는 경험이 부족하여 생소하게 느껴졌을 수도 있습니다.
이번 2주 차 강의를 통해 객체 지향적인 부분이 고려되지 않은 코드에서 리팩토링을 진행하며 어떤 기준에서 클래스나 메서드를 분리하는지, 객체 지향적인 코드를 작성하는 것의 장점은 무엇이고 테스트 코드와는 어떤 연관이 있는지를 알 수 있게 됩니다.
사다리의 상태를 표현할 때 0, 1, -1 등을 사용했습니다. 이런 하드 코딩된 상수는 의미를 알기 어렵고 enum 값으로의 분리가 필요합니다.
예외 처리에 관한 메시지에서도 여러 군데에서 사용되는 공통적인 부분이 있기 때문에 enum 값으로 관리해줄 필요가 있어 보입니다.
또한 코드를 살펴보면 생성자에선 자연수 값을 사용해 배열을 초기화하고, drawLine, run 메서드에선 인덱스 값이 사용됩니다. 이런 부분에 대해서도 값의 범위에 대한 검증 로직이 필요하고, 코드를 사용하는 입장에서 변수 명을 보고 이를 판단하기 힘들 수 있습니다. 의미를 가지는 원시값을 그대로 사용했기에 발생하는 문제로 래퍼클래스를 활용해 분리해 의미를 부여하고, 검증 로직을 포함해 코드 응집성을 높일 수 있습니다.
2차원 배열을 사용하는 이유는 행과 열의 기능이 다르기 때문입니다. 각 행과 열이 맡고있는 책임이 다름에도 모든 값들을 같은 자료형이나 객체로 표현하는 것은 객체 지향적이지 않다고 생각했습니다. 또한 2차원 배열은 내부 값을 다루다 보면 2중 반복문 등이 들여쓰기가 남발될 수 있고, 이러한 중첩은 메서드가 복잡해지고 무거워지는 원인이 되어 가독성이 좋지 못합니다. 때문에 2차원 배열을 1차원 배열 두개로 분리하면 좀 더 객체 지향적인 코드를 작성할 수 있습니다. 또한 사다리 각 칸에 대한 부분도 단순히 int로 사용하기에는 설명이 부족해보입니다. 각 칸도 분명한 의미를 가지고 책임이 있기 때문에 이 부분도 클래스로 만들어 주겠습니다.
// 기존
int[][] ladder;
// Row 도입
Row[] rows;
public class Row {
private final Node[] nodes;
..
}
public class Node {
private Direction direction; // 0, 1, -1 enum
private Node(Direction direction) {
this.direction = direction;
}
..
}
이 처럼 한 행을 Row 클래스로 분리하고 각 칸을 Node 클래스로 분리 하고 각 책임에 맞는 메서드를 부여합니다.
그렇게 되면 Ladder -> Row -> Node 로 필요한 메시지를 전달하며 객체 지향적인 코드를 작성할 수 있습니다.
Ladder 클래스를 보면 현재 너무 많은 책임을 가지는 것 같습니다. 사다리의 생성부터, 사다리 그리기, 진행... 등등의 많은 책임을 가지는데 이 또한 책임에 따라 클래스를 분리해주겠습니다
리팩토링 후 코드는 https://github.com/Konkuk-KUIT/KUIT4_Server-Ladder/tree/1week-completed 에서 확인할 수 있습니다.
2주 차 미션은 강의에서 리팩토링 한 코드에서 시작합니다.
대략적인 요구사항은 아래와 같습니다. 자세한 요구사항과 구현 힌트는 부원들에게 따로 미션북을 통해 제공했습니다.
// 0 번째로 들어온다.
Before
1* -1 0 0 0
0 1 -1 0 0
0 0 0 0 0
0 0 0 0 0
// 사다리의 1을 만났으니 왼쪽으로 이동한다.
After
1 -1* 0 0 0
0 1 -1 0 0
0 0 0 0 0
0 0 0 0 0
// 이동 후 아래로 한칸 내려간다.
Before
1 -1 0 0 0
0 1* -1 0 0
0 0 0 0 0
0 0 0 0 0
// 반복 ...
After
1 -1 0 0 0
0 1 -1* 0 0
0 0 0 0 0
0 0 0 0 0
Before
1 -1 0 0 0
0 1 -1 0 0
0 0 0* 0 0
0 0 0 0 0
After
1 -1 0 0 0
0 1 -1 0 0
0 0 0* 0 0
0 0 0 0 0
LadderGame
에 LadderCreator
를 변경할 수 있도록 한다.LadderGame
을 생성한다. 1주 차와 마찬가지로 2주 차 미션이 제출되면 같은 방식으로 코드 리뷰를 제공합니다.
내용이 더 심화된 만큼 기본적인 객체 지향적 관점에 어긋나는 부분을 중심으로 코드 리뷰를 진행했습니다. 클래스에 명확한 책임을 부여하는지, 메서드가 하나의 일을 하고있는지, 객체간 메시지를 전하며 협력이 원활히 이뤄지는지 등을 확인했습니다. 또한 강의에서 강조한 내용이나 미션북에서 제공된 내용과 키워드를 성실히 수용했는를 중심으로 코드 리뷰를 진행했습니다.