기간: 2025.01.13 ~ 2025.01.31 (6주 차)
01. 학습 내용
(1) JAVA 블로그 요약정리 (Ch 11 ~ Ch 14)
(2) 네트워크 정리
(3) JAVA 과제 - Poker Game 만들기
02. Poker Game 과제
저는 항상 과제나 프로젝트를 들어가기 전, 이 프로젝트의 목적과 주 활용도, 요구사항이 뭔지를 파악하는 것이 가장 중요하다고 생각합니당. 그래서 전체 프로젝트 기간이 100이라면 요구사항 파악과 정의가 40, 실제 구현(코딩)이 30, 테스트 및 유지보수에 30에 시간을 쓰는 것 같아요. 프로젝트를 구조화하고 설계를 완벽하게 한다면 내가 아는 지식으로 구현(코딩)하는 것은 글을 받아쓰기와 같아요. 그래서 저는 가장 중요하다고 생각합니당.
과제를 받으면 제약사항도 많고, 처음 보는 룰도 많은 경우가 많아요. 그래서 내가 이론에 빠삭하더라도, 당장 코딩부터 시작하면 무엇을 어떻게 어디에 활용해야 하는지 막막하더라구요. 요구사항 정의는 내가 알고 있는 이론을 어디에 어떻게 적용할 수 있는지 전체적인 화면을 본다고 저는 생각합니당.
근데 이제 요구사항을 작성할 때, 저는 너무 디테일한 부분은 배제하고 시작해요. 제 옛날 취미가 그림 그리는 것이었는데, 예를 들어 사람을 그린다고 하면 눈코입부터 그리고 얼굴, 몸 전체 순서로 그리면 비율이 이상해지잖아요? 전체적인 스케치로 틀을 잡고, 그 안에서 수정하며 진행하며 그리는 것과 마찬가지로 코딩도 똑같다고 생각해요. 그래야 전체적인 부분에서 문제가 생겨 보인다 싶으면 초기 부분에서 바로 잡을 수 있으니까요. 가장 중요한 부분들을 찾아 추상화시켜서 전체적인 부분을 보는 게 중요해요.
요구사항 정의도 너무 어렵게 생각하지 마시고 주어진 과제를 내 언어로 정리하면서 파악하고, 전체적인 흐름을 찾아보면 코딩은 그냥 그것을 실제로 구현해 주는 언어라고 생각합니당. 처음 과제를 받고 과제의 내용이 길고 요구사항이 많아 어렵다고 하신 분들도 계시던데, 너무 어렵게만 생각하지 않으셨으면 좋겠어서 도움이 될진 모르겠지만 제가 어떤 순서로 과제를 진행하는지 공유해볼게용.
아래의 사진들(시퀀스 다이어그램 제외)은 제가 지하철을 기다리면서 후딱 쓴 거라 글씨가 엉망이지만 이런 방식으로 진행했구나만 봐주셨으면 좋겠습니당..ㅎㅎ, 참고로 검은색 글씨로 한번 정리 후, 다시 2회 차로 보면서 초록색 글씨를 추가한 거예요. 저도 처음부터 자세하게 진행하지 않습니다!!
저도 다 같이 하는 프로젝트에서는 요구사항을 모두가 알아볼 수 있게 형식화된 것을 사용하는 것을 좋아하지만, 혼자 하는 프로젝트는, 특히 처음 해보는 경우에는 이렇게 낙서하듯이 정리해 보는 것도 괜찮다고 생각해요. 이렇게 요구사항을 정리하면 과제에 쓰여있는 룰을 읽는 것과 다르게 이해하는데 도움이 되더라구용.
요구사항을 다 정리한 것 같으면, 이제 이 프로젝트가 어떤 흐름으로 흘러가는지 머릿속으로 말고!! 직접 그려보는 것이 좋아용. 사실 이 부분에서 많은 시간을 쓰고 정리한다면, 코딩하는 시간이 훠어얼씬 줄어드는 것을 느낄 수 있어요. 이 흐름도를 그리려면 앞서 진행한 요구사항도 잘 정리해야 기능을 흐름에서 빠짐없이 그릴 수 있겠죠? 근데 너무 디테일하게는 말고 전체적인 가장 중요한 흐름으로 하는 것이 중요해용.
사실 흐름도를 그리고 코딩을 시작해도 되지만, 저는 시퀀스 다이어그램을 그려보고 구현을 했습니당. 저희가 하는 것은 객체지향적으로 구현을 하는 것이잖아요? 시퀀스 다이어그램은 객체 간의 상호작용을 시간 순서에 따라 표현한 것이고, 흐름도는 프로세서나 알고리즘의 흐름을 시각화한 것이므로, 흐름도를 그렸는데 막상 코딩을 하려니 어떤 객체가 언제, 어디서 생성, 사용되어야 하는지 파악이 안 될 경우 저는 사용합니다. 시퀀스 다이어그램은 복잡하고 한눈에 파악이 안 되는 시스템의 상호작용(로그인, 주문 처리) 등에 아주 유용해서 저는 파악이 잘 안 될 경우 자주 이용합니다.
이렇게 정리하고 나서 하는 구현과 바로 구현하는 것은 많은 차이가 있겠죠??! 가장 중요한 것은 내가 코딩하면서 수정과 추가를 계속 진행하잖아요, 그때 내가 이 부분을 건드리면 어떤 부분에서 문제가 생기는지 아는 것과, 그 부분을 건드렸을 때, 상관없는 부분에서는 문제가 없어야 하는 것이 가장 중요해요. 이것만 고려해서 설계하면 유지보수와 테스트할 때 아주 유용할 것이라고 생각합니당.
그리고 단위 테스트를 많이 해보셨으면 좋겠어요. 코딩은 모든 게 다 설계된 후 테스트를 하는 것은 효율적으로 좋지 않다고 생각합니다. 내가 한 기능을 구현했다면, test 클래스를 만들어서 여러 조건을 넣어서 내가 원하는 결과를 내는지 확인하는 것이 구현보다 중요하다고 생각해요. 깃허브에도 있지만, 예를 들어 제가 했던 테스트를 보여드릴게요.
class DealerTest {
static Dealer dealer;
@BeforeAll
public static void setting(){
dealer = new Dealer();
}
@Test
void dealerTest1() throws Exception{
if(!dealer.getNickName().equals("딜러"))
throw new Exception("이름 오류");
if(!dealer.getRole().equals("DEALER"))
throw new Exception("역할 오류");
}
@Test
void dealerTest2() throws Exception{
ArrayList<Card> cards = Dealer.cards;
int num = 0;
for(Card c : cards){
num++;
System.out.println(c.getPatternEgl() +"("+c.getPattern()+") "+ c.getNumber());
}
if(num != 52)
throw new Exception("카드 생성 오류");
else
System.out.println("dealerTest2: 카드 생성 끝");
}
@Test
void dealerTest3() throws Exception{
ArrayList<Card> cards = Dealer.cards;
dealer.shuffleCards();
for(Card c : cards){
System.out.println(c.getPatternEgl() +"("+c.getPattern()+") "+ c.getNumber());
}
System.out.println("dealerTest3: 출력 끝");
}
@Test
void dealerTest4() throws Exception{
dealer.shuffleCards();
ArrayList<Card> cards = dealer.handOutCard();
for(Card c : cards){
System.out.println("카드 나눔: "+c.getPatternEgl() +"("+c.getPattern()+") "+ c.getNumber());
}
int num = 0;
for(Card c: Dealer.cards){
num++;
}
if(num != 47)
throw new Exception("카드를 나눠주고 삭제가 안됨");
System.out.println("dealerTest4: 출력 끝");
}
@Test
void dealerTest5() throws Exception{
ArrayList<Card> cards = dealer.handOutCard();
int num = 0;
for(Card c: Dealer.cards){
num++;
}
if(num != 42)
throw new Exception("카드를 나눠주고 삭제가 안됨");
dealer.receiveCard(cards);
num = 0;
for(Card c: Dealer.cards){
num++;
}
if(num != 47)
throw new Exception("카드를 받지 못함");
System.out.println("dealerTest5: 출력 끝");
}
}
이 코드는 Dealer 객체의 기능을 테스트한 것입니당. 딜러가 가지고 있는 기능들이 많잖아요? 그 기능들은 대부분 이 Dealer 클래스를 만들 때 한 번에 구현합니다. 그런데 막상 구현하고 실행하니까 딜러가 생성이 안된다거나, 딜러가 카드를 가지고 있지 않다던가, 카드를 섞지 않는다는 가 등등의 문제가 발생할 수 있어요. 그런데 그 오류를 한눈에 파악해서 수정하면 좋겠지만, 프로젝트가 커질수록 여러 곳과 관련된 부분이 많아지면 파악하기 힘들어지더라구요.... 그래서 기능을 구현하면 딱! 그 기능을 테스트하는 테스트를 돌려서 각각의 기능이 제기능을 하는지 확인해서 수정하는 것이 시간 단축에 좋습니다. 또 디버거를 사용하는 것을 익히는 게 좋아용. 내가 만든 흐름도와 디버거가 흐름대로 진행되는지 확인하기 좋더라구용.
03. 6주 차 학습 스케줄 점검
04. 회고록
위의 내용들이 사실 뻔하며 당연한 내용이고 다들 아시고 있을 수도 있지만, 저는 JAVA 뿐만 아니라 여러 다양한 언어를 이용한 프로젝트들에서도 공통적으로 유용하고 효율적인 방법이라고 생각해서 이번 과제를 하면서 가장 중요하다고 생각해서 공유하고 싶었어요. 어려운 건 처음 보는 룰과 기능들이 어려운 거지, 코딩이 어려운 게 아니라는 것을 알고 어려운 것을 집중해서 정리하고 이해한다면 뭐든 구현 가능하다는 것을 말하고 싶었습니당 !!
말이 많았지만 도움이 되셨으면 좋겠고 제 방법이 항상 옳은 건 아니니까 여러 방법과 다이어그램으로 정리해 보고, 다양한 방법으로 자신만의 방법을 찾으셨으면 좋겠어요!! 다들 이번 주도 고생 많으셨습니다 ♥
'회고록' 카테고리의 다른 글
[회고록] 패스트캠퍼스 백엔드 부트캠프 3기 (4) | 2025.02.17 |
---|---|
[회고록] 패스트캠퍼스 백엔드 부트캠프 3기 (0) | 2025.02.10 |
[회고록] 패스트캠퍼스 백엔드 부트캠프 3기 (3) | 2025.01.20 |
자바 목차 테스트 (1) | 2025.01.15 |
[회고록] 패스트캠퍼스 백엔드 부트캠프 3기 (1) | 2025.01.13 |