설모의 기록
[우아한테크캠프] 2일차 본문
Code Convention?
개발자라면 어느 언어를 사용하느냐에 관계없이 코드 컨벤션의 중요성을 알 것입니다. 코드 스타일이 다른 사람들과 협업을 하다보면 코드를 구현하는 시간보다 동료의 코드를 이해하는 시간이 더 오래 걸립니다. for문의 body를 감싸는 괄호를 한 줄 띄우냐, 안 띄우냐로도 신경쓰이기 때문이죠.
코드 컨벤션은 기본적으로 언어마다 지켜야 할 규칙이 있지만 그 이외의 부분에서는 팀원들과 상의하여 규칙을 모두 정해야 합니다. 코드 컨벤션 규칙을 정하고 협업을 시작하면 코드를 읽는데에도, 유지보수하는데에도 상대적으로 적은 시간이 걸립니다. 오늘 제가 우아한테크캠프에서 배운 간단한 코드 컨벤션은 아래와 같습니다.
1. 클래스 명은 대문자로, 메소드 명은 소문자로 시작하기
public class Car {
private int position;
private String name;
public Car(int position, String name) {
this.position = position;
this.name = name;
}
int getPosition() {
return position;
}
public String getName() {
return name;
}
}
위의 예제에서 보다시피, Car클래스의 시작은 대문자 C로, getPosition()과 getName() 메소드의 시작은 소문자 g로 시작합니다. 이 규칙은 앞글자만 보고도 클래스인지 메소드인지를 구분하기 위해 정해진 규칙입니다.
2. 패키지 명은 소문자로 시작하며, 가급적 한 단어로 구성하기
위의 예제에서 보면 calculator, coordinate, racingcar와 같이 패키지명은 소문자로 시작해야합니다. '두 단어가 필요한 이름은 어떡하지?' 라는 고민이 든다면 그 순간부터 잘못된 이름입니다. 패키지명은 한 단어로 구성해야합니다. 굳이 두 단어를 이용해야 한다면 아래의 예제와 같이 하시면 됩니다.
게임 프로젝트를 예로 든다면, lobbyScene 패키지와 gameScene이 필요할 수 있습니다. 이럴 땐 scene패키지 안에 main과 lobby 패키지를 추가하는 것이 좋습니다. 그래서 패키지를 접근할 때는 scene.game 과 scene.lobby로 접근하시면 됩니다.
3. 메소드 분리는 항상 고민하기
이전에는 하드웨어의 성능이 낮았기 때문에 하드웨어의 비용을 줄이기 위해 메소드를 분리하지 않고 한 곳에 구현하는 경우가 많았습니다. 그러나 요즘에는 하드웨어의 성능이 너무나도 좋아졌습니다. 그래서 하드웨어의 비용을 줄이는 것보다 읽기 좋은 코드로 구현해 유지보수하는 사람이 일하는 비용을 줄이는 것이 더 효율적인 세상이 됐습니다. 따라서 메소드를 구현하는데에 있어서 아래의 작업을 고민해야 합니다.
한 메소드에는 최대한 한 가지의 작업만 하도록 구현하며, 그 작업과 관련된 이름으로 메소드의 이름을 설정해야 합니다.
메소드 안에서의 코드들은 한 가지의 추상화 단위로 구현해야 합니다. 어느 한 코드만 구체적이거나 추상적이면 안된다는 이야기입니다.
메소드 안의 코드는 top-down 방식으로 구현해야 합니다. 코드의 흐름이 위에서 아래로 자연스럽게 흘러야 한다는 이야기입니다.
메소드의 이름은 서술적으로 지어야 합니다. 메소드 내에 여러 작업이 있다면 and와 같은 단어를 사용해도 됩니다. Car 클래스를 예로 들면, 메소드 안에서 차가 10m 움직인 후 멈추는 작업을 해야 한다고 가정해 봅시다. 그렇다면 메소드 명을 'stopAfter10Move()' 이런식으로 구현해도 된다는 이야기입니다. 그러나 and, after와 같은 단어들이 메소드명으로 생각난다면 '메소드를 더 나눌 수 없을까?', '하나의 메소드가 너무 많은 작업을 하는 것은 아닐까?' 라는 고민을 해봐야 합니다.
메소드의 인자는 0개인 것이 이상적입니다. 1 ~ 2개 까지는 괜찮지만 3개는 가급적 피해야 하며, 4개부터는 불가능하다고 생각하고 코드를 구현해야 합니다. 인자가 많아진다면 클래스 객체로 추출하는 것을 고민하는 것이 좋습니다.
예를 들어, draw(int x, int y, int radius) 라는 메소드는 draw(circle) 이런 식으로 Circle 객체인 circle을 draw의 인자로 넘기는 것이 좋습니다.- side effect를 일으키는 메소드는 가급적 피해야 합니다. side effect가 많으면 예상치 못한 버그가 발생할 수 있기 때문입니다.
- 만약 메소드가 데이터베이스와 관련되어 있다면, 가급적 명령과 조회를 분리하는 것이 좋습니다.
- 중복코드는 소프트웨어에서 모든 악의 근원입니다. 중복코드를 없애고 하나의 메소드로 따로 구현하는 것이 좋습니다.
4. Test Code를 작성하기 쉽도록 코드 작성하기
이전에는 Java 프로젝트나 안드로이드 프로젝트를 구현할 때 디버깅을 이용해 코드의 문제점을 찾았는데요. 우아한테크캠프에서 테스트 코드를 작성하는 방법을 배우고 유용함을 깨달았습니다. 이를 이용하기 위해서는 test code로 작성하기 쉽도록 실제 구현 코드를 작성하는데에 노력해야 합니다. 아래의 예제를 보겠습니다.
void move() {
if (getRandomNumber() >= 4) {
this.position++;
}
}
int getRandomNumber() {
return new Random().nextInt(10);
}
위의 예제로 Test Code를 작성할 수 있을까요? 정답은 만들 수 없습니다. 일단 move의 반환형이 void이며 내부에서 getRandomNumber() 메소드를 사용하고 있기 때문에 random number를 임의적으로 테스트 해볼 수 없습니다. Test Code를 작성하기 위해서는 위의 코드를 아래와 같이 수정해야 합니다.
int move(int randomValue) {
if (randomValue >= LIMIT_NUM)
this.position++;
return this.position;
}
int getRandomNumber() {
return new Random().nextInt(10);
}
위와 같이 작성한다면 move의 테스트 코드를 작성할 수 있습니다. move의 테스트 코드는 아래와 같습니다.
public class CarTest {
private Car car;
@Before
public void setUp() throws Exception {
car = new Car(2, "hyeona`s Car");
}
@Test
public void move() {
assertThat(car.move(4)).isEqualTo(3);
}
}
위와 같이 4라는 값을 임의로 넣어 코드를 테스트 해볼 수 있습니다.
이렇게 테스트 코드를 작성하기 위해서는 실제 코드에서 지켜져야 할 규칙이 있습니다.
불확실성을 없애야 합니다. 그 예로는 랜덤수, 임의시각, 전역변수, db의 특정 레코드, http의 get방식과 같은 코드입니다.
side effect를 없애야 합니다. 그 예로는 전역변수, 로컬 머신에 존재하는 파일 내용( 예: Scanner 사용, System.out.println() ), db 특정 레코드를 수정하는 작업, http의 post방식과 같은 코드입니다.
순수함수로 구현해야 합니다. 이를 위해서는 함수 내에 불확실성과 side effect가 없어야 합니다.
void 보다는 반환 값이 존재하는 함수로 구현하는 것이 좋습니다. 그래야 테스트 코드를 통해 값을 확인할 수 있기 때문입니다.
테스트하기 쉬운 코드와 테스트하기 어려운 코드로 메소드를 최대한 분리해야 합니다.
이외의 Java에서의 코드 컨벤션이 궁금하시면 Oracle 홈페이지를 확인해보시면 좋을 것 같습니다! 혹시 intellij 개발툴을 사용하신다면 cmd + option + L 단축키를 사용하시면 java 컨벤션에 따라 코드가 조정되니까 조정된 코드를 보면서 익혀나가시면 됩니다. 정해지지 않은 코드 컨벤션은 팀원들과 함께 정해나가시면 더욱 효율적인 협업을 하실 수 있습니다.
'일상 > 우아한테크캠프' 카테고리의 다른 글
[우아한테크캠프] 7일차 (0) | 2018.07.11 |
---|---|
[우아한테크캠프] 6일차 (0) | 2018.07.09 |
[우아한테크캠프] 5일차 (0) | 2018.07.07 |
[우아한테크캠프] 4일차 (0) | 2018.07.06 |
[우아한테크캠프] 3일차 (0) | 2018.07.04 |