본문 바로가기
우아한테크코스

우아한테크코스(프리코스) 1주차 회고

by 임동무 2022. 11. 1.

우테코 프리코스 1주차가 끝났다.

이 1주일이라는 기간은 나에게 너무나 혹독한 반성의 시간이었던 것 같다.

 

1. 자바 컨벤션? 

첫 번째로 힘든 점은 구글 스타일의 자바 컨벤션을 지키는 것이었다

(구글 스타일과 다른 점은 블럭 들여쓰기가 +2 가 아닌 +4 , 가독성을 위한 개행은 어디든지 허용,

열 제한은 120자, 들여쓰기 지속은 최소 +8 인 점이었다.)

 

기존에 공부를 하고 코드를 작성하면서 컨벤션이라는 것을 지켜본 적, 아니 들어본 적도 없었다. 그래서 구글 스타일의 자바 컨벤션을 번역해가며 정독했음에도 컨벤션을 지키면서 코딩한다는 것이 쉽지 않았고 심지어는 변수명, 메소드명을 어떻게 해야할 지 고민하면서 수 많은 시간을 보내면서 코딩을 시작하기조차 힘들었다.

(아래는 구글 자바 스타일 가이드 입니다)

 

https://google.github.io/styleguide/javaguide.html

 

Google Java Style Guide

1 Introduction This document serves as the complete definition of Google's coding standards for source code in the Java™ Programming Language. A Java source file is described as being in Google Style if and only if it adheres to the rules herein. Like ot

google.github.io

 

 


2. 메소드 분기

그 다음으로 힘들었던 점은 메소드 분기였다.

우테코에서는 메소드를 최대한 작게 만들어서 메소드 하나는 하나의 기능만 하도록 하는 것을 요구한다. 비단 우테코만의 요구사항은 아닐 것이다. 또한 메소드 하나의 들여쓰기는 하나의 레벨만 허용한다. 하지만 이 부분은 컨벤션을 지키는 것보다 힘들었다. 

 

처음에는 메소드를 하나의 기능만 담당하고, 모든 구문이 의미를 가지도록 모든 기능 하나하나를 전부 메소드화 시켜서 사용했었다. 예를 들어 list.get() 을 사용할 때에도 get~~(List<> list){ return list.get(); } 메소드를 정의하여 사용하였고 두 정수의 합을 구할 때도 메소드를 따로 정의해서 이름을 부여해야겠다고 생각했다. 

 

그렇게 한 문제를 풀고 보니 하나의 간단한 문제 안에 너무 많은 메소드가 정의되어 있었다. 그렇게 되니

1. 오히려 메소드가 너무 많아서 정신없는(가독성이 좋지 않은) 코드가 되었고

2. 비슷한 이름의 메소드가 많아졌고

3. 메소드의 논리적인 순서를 짤 때, solution 메소드에서 1,2,3 의 순서로 메소드를 호출하고 1,2,3 메소드는 각각 1-1,2-1,3-1 의 메소드를 호출한다면 메소드의 논리적인 순서를  solution , 1, 1-1, 2, 2-1, 3, 3-1 의 순서로 메소드를 위치시켰는데 이 순서가 뒤죽박죽이 되어버렸다. 

 

이를 어떻게 해결할 지에 대해서 고민한 끝에 내가 내린 해결책은

" 메소드의 이름을 부여하는 것은 메소드가 어떤 기능을 하는지 정확하게 명시해주기 위해서이니, 메소드 명을 짓는데에 집중하고 a+b 나 list.get() 처럼 어떤 작업을 할건지를 정확하게 알 수 있는 경우에는 메소드를 정의할 필요성을 확인하고 필요가 없을 것 같다면 연산의 결과물을 저장할 변수명을 적절하게 정의해주는 것만이 중요하다. "  는 것이었다.

 

이후로는 메소드를 단순히 작게 만들고 간단한 연산들에게도 메소드를 부여하는 것에 집중하는 것이 아니라,

메소드를 작게 만들면서 동시에 메소드명에 집중하여 메소드를 정의하고 간단한 연산은 변수명을 어떻게 지을 것인지에 집중하였다. 

 

이런 작업을 하면서 나에게는 상당한 변화가 생겼다. 

바로 코드를 작성하기 전에 고민하는 시간이 생겼다는 것이고 또한 이 고민하는 시간이 상당히 길었다. 

 

그 전에는 손이 가는대로 코딩하고, 코딩하다가 빨간줄이 뜨거나 컴파일 오류가 발생하면 수정하고 이런 식으로 프로그래밍을 했다면 이번 우테코 1주차에서는 먼저 하나의 요구사항에 대해서 기능 목록을 작성하고, 각 기능마다 어떤 메소드를 정의해서 사용할 건지, 메소드는 어떻게 명명할 것인지 등에 대해서 전체적인 흐름에 대해서 고민을 먼저 한 다음에 전체적인 윤곽이 잡히면 코딩을 시작했다. 

 

물론 그렇게 고민 끝에 코팅을 하면서도 중간에 수정사항이 많이 생겼다. 생각하지 못한 부분에 대한 수정사항도 생겼고 더 나은 방향으로 수정하기도 했다. 

 

이렇게 전체적은 틀을 짜놓고 계속 생각하면서 코딩을 하다보니 스스로의 코드를 리뷰하면서 계속해서 나은 방향을 고민해보는 역량이 키워진 것 같다. 이 전에는 독학으로 공부하다보니 누군가가 내 코드를 좀 피드백을 해주기를 기대했었는데 다른 사람에게 코드리뷰를 받는 것도 물론 좋지만 먼저 자신의 코드를 돌아보아야 한다는 것을 배웠고 그 기준에 대해서 배울 수 있게 된 것 같다. 

 


3. else 예약어를 사용하지 말자.

사실 처음 클린코드 원칙을 접하고 가장 뜬금없다고 느껴졌던 부분이었다. 

"엥? else 문을 사용하지 말라고?" 라고 생각해서 왜 사용하면 안될 지에 대해서 구글링을 해봤다.

찾은 문제점에 대해서는

 

1. 확장에 닫혀있어 개방폐쇄원칙에 어긋난다
 - 계속해서 조건이 추가되는 경우 if 블럭이 굉장히 방대해지고 그렇게 되면 각 조건에 따른 분기가 어떤 의미인지 파악하기 힘들다. 즉, 조건이 추가될수록 코드의 가독성이 떨어지고 유지보수에도 어려움을 겪을 가능성이 커진다.

2. 가독성이 좋지 않다.
 - 앞서 언급한 내용과 같이 가독성이 떨어지는 코드가 된다.

3. 실수로 누락하는 경우가 생길 수 있다.
 - 방대한 if~else 의 조건은 보통 복사 붙여넣기를 통해 앞서 정의한 내용을 그대로 가져와서 쓰는 경우가 대부분이다. 그렇기 때문에 누락하는 경우가 생길 수 있다. 

 

등의 문제가 있다고 한다. 

 

이를 해결하기 위해서는

1. 조기 return 을 통해 조건마다 return 값을 명시해주면 각 조건에 따른 의도를 파악하기가 비교적 용이해진다. 
2. 각 조건과 조건에 따른 값을 가지고 있는 가지는 enum 클래스를 정의하여 사용한다.
3. enum 과 비슷한 맥락으로 Map 을 사용한다. 

등의 해결책이 있었고 else 문 대신 이런 방법을 이용하여 구현하기 위해 신경쓰는 부분에서도 시간이 많이 소요됐다.

 

 

 


4. 일급 컬렉션

제출 전 확인사항에서 "일급 컬렉션을 사용했는가" 를 마주하게 되었다. 

아예 처음 들어보는 내용이었고 바로 검색해보았다. 

 

일급 컬렉션이란 컬렉션을 Wrapping 하면서 동시에 해당 컬렉션 하나만 변수로 가지며 다른 멤버 변수가 없는 클래스를 의미한다.

사용하는 이유는

1. 비지니스에 종속적인 자료구조를 만들 수 있다. 

2. 행위와 상태를 같은 공간에서 관리한다.

3. 불변성을 보장

4. 컬렉션에 이름을 부여

정도가 있다.

 

1. 비니지스에 종속적이다. && 행위와 상태를 같은 공간에서 관리한다.

- 일반적으로 검증로직은 private 메소드를 통해 Service 단에서 처리하는 경우가 많다.

그렇기 때문에 검증 로직이 많아야 하는 경우나 처음 해당 코드를 접하는 경우 검증 로직의 각각의 역할을 파악하는 것이 쉽지만은 않다. 

 

또한 일반적으로 컬렉션을 사용하는 경우 컬력선 모든 요소의 총 합, 컬렉션에서 어떤 값을 가져오기 등 모든 행위는 컬렉션과 같은 공간에서 이루어지지 않는다. 

 

하지만 일급 컬렉션은 해당 컬렉션을 Class로 Wrapping 하고 그 컬렉션을 이용한 모든 기능들을 그 Class 내부에서 모두 관리할 수 있다. 즉, 행위와 상태를 같은 공간에서 관리할 수 있다는 것이다. 이렇게 되면 그 컬렉션과 관련된 문제가 있을 때, 컬렉션에 대한 모든 로직과 데이터가 모여있기 때문에 유지보수에 굉장히 유리하다. 

뿐만 아니라, 검증로직 또한 Class 내부에서 관리할 수 있다. 이를 이용하면, 컬렉션을 이용해서 일급 컬렉션의 Class 를 호출했을 때, 생성자 내부에서 검증로직을 실행시킬 수 있어 비지니스에 종속적인 자료구조로 만들 수 있다. 

 

 

2. 불변성을 보장한다.

- 보통 불변 컬렉션을 사용할 때에는 final 을 이용한다. 하지만 정확한 final 의 의미는 불변이 아니라 재할당 불가능이다. 

final 로 선언한 List 에 add() 는 가능하지만 new ArrayList<>(); 로 재할당이 불가능하다는 의미이다. 

 

하지만 이를 Wrapping 하고 wrapping 된 컬렉션에 직접적으로 접근하지 못하도록 접근제어자를 설정하고 setter 를 정의하지 않는다면 그 컬렉션은 불변을 보장받을 수 있다.

 

 

3. 컬렉션에 의미를 부여

- 보통은 컬렉션에 의미를 부여할 때 변수명을 이용하여 이름에 대한 의미를 부여한다. 

하지만 이렇게 사용한다면 전체적인 구조를 정확하게 파악하고 있지 않는 한, 특정 List 를 검색해서 찾을 수 없기 때문에 찾기가 어렵다.

 

하지만 Wrapping 되어 의미가 부여된 컬렉션의 경우에는 Class 를 이용한 검색을 통해 쉽게 호출된 위치를 찾을 수 있고, 개발자들 끼리 혹여 다른 변수명을 사용했더라도 사용된 위치를 찾을 수 있다. 

 

 

 

 

일급 컬렉션의 경우에는 많이 찾아보고 사용하기 위해 노력은 했지만 사실 맞게 사용했는지는 의문이다.

하지만 일급 컬렉션을 통해서 객체지향적인 코드가 뭔지 조금 알 수 있었던 것 같다. 

 

일급 컬렉션은 특정 컬렉션을 멤버변수로 가지고 있으면서 그 멤버 변수와 관련된 모든 것을 관리한다. 즉, 하나의 객체가 하나의 역할을 확실하게 책임지고 있다는 것이다. (내가 이해한 내용이 틀릴 수도 있지만)

 

 

 

 

 

 


1주차 총평 :

앞서 언급한 것 처럼 프리코스의 1주일은 혹독한 반성의 시간이었다. 

프로코스를 진행하면서

"나는 자바를 사용하면서 자바를 몰랐다. 객체지향적인 코드가 뭔지 몰랐다. 나는 나만 보려고 코드를 짰다." 등 부족한 부분이 너무나도 많다는 것을 느꼈다. 

 

프리코스를 시작하기 전에 했던 오리엔테이션에서 프리코스 4주만으로도 충분한 성장을 할 수 있을 것이라고 호언장담하던 포비의 말을 처음에는 반신반의 했다. 하지만 4주만으로 성장할 수 있을 것이라는 포비의 말은 

"4주동안 성장시켜줄게" 가 아니라

 

"4주동안 성장할 수 있는 길을 만들어줄테니 그 길을 따라 스스로 걷다보면 4주동안 충분한 성장을 할 수 있을 것이다." 라는 의미였던 것 같다.

 

이번 1주차만 해도 마치고 나니 배운이 너무나도 많고 부족하다고 생각해서 앞으로 공부해야할 내용도 너무나도 많다는 것을 느꼈다.

남은 3주동안에도 느리고 중간중간 틀릴 때도 있겠지만 프리코스에서 만들어놓은 길을 따라 나아가며 완주하기 위해 최선을 다해야겠다!!

댓글