코딩 컨벤션 (Coding Convention)
1. 개요
코딩 컨벤션(Coding Convention)이란 소프트웨어 개발 시 코드의 가독성을 높이고 유지보수를 용이하게 하기 위해 개발자 간에 약속한 일관된 코드 작성 규칙의 집합을 의미한다.
현대의 소프트웨어 개발은 단독 작업보다는 팀 단위의 협업으로 이루어지는 경우가 많다. 개발자마다 선호하는 작성 스타일이 다를 경우, 동일한 로직이라도 표현 방식이 달라져 코드 리뷰 시간이 늘어나고 버그를 발견하기 어려워지는 문제가 발생한다. 따라서 일관된 코딩 컨벤션을 적용함으로써 '누가 작성했든 마치 한 사람이 작성한 것과 같은' 상태를 유지하는 것이 협업 효율성 극대화의 핵심이다.
2. 주요 구성 요소
코딩 컨벤션은 단순히 띄어쓰기를 맞추는 것을 넘어, 코드의 구조와 의미 전달 방식을 규정하는 다양한 항목을 포함한다.
2.1 명명 규칙 (Naming Convention)
식별자(변수, 함수, 클래스 등)의 이름을 짓는 규칙이다. 가장 널리 쓰이는 방식은 다음과 같다.
- lowerCamelCase: 첫 단어는 소문자로 시작하고 이후 단어의 첫 글자를 대문자로 표기 (예: userName)
- PascalCase (UpperCamelCase): 모든 단어의 첫 글자를 대문자로 표기 (예: UserAccount)
- snake_case: 모든 글자를 소문자로 쓰고 단어 사이를 언더바(_)로 연결 (예: user_name)
- kebab-case: 모든 글자를 소문자로 쓰고 단어 사이를 하이픈(-)으로 연결 (예: user-name)
- SCREAMING_SNAKE_CASE: 모든 글자를 대문자로 쓰고 단어 사이를 언더바(_)로 연결 (예: MAX_RETRY_COUNT)
[언어별 일반적인 명명 규칙 비교]
| 대상 |
Java |
Python |
JavaScript |
C# |
| 클래스 |
PascalCase |
PascalCase |
PascalCase |
PascalCase |
| 변수/필드 |
camelCase |
snake_case |
camelCase |
camelCase |
| 함수/메서드 |
camelCase |
snake_case |
camelCase |
PascalCase |
| 상수 |
SCREAMING_SNAKE |
SCREAMING_SNAKE |
SCREAMING_SNAKE |
PascalCase |
2.2 들여쓰기 및 공백 (Indentation & Whitespace)
- 들여쓰기: 탭(Tab)을 사용할지, 공백(Space) 2칸 또는 4칸을 사용할지 결정한다.
- 공백: 연산자 주변의 공백(
a+b → a + b), 괄호 안쪽의 공백 여부 등을 규정한다.
- 문서화 주석: API나 클래스의 역할을 설명하는 Javadoc, TSDoc 등의 표준 형식 사용.
- 인라인 주석: 복잡한 로직에 대해 '왜(Why)' 이렇게 작성했는지를 설명하는 주석 작성.
2.4 파일 및 폴더 구조
- 파일명 명명 규칙 (예:
user.controller.ts 또는 UserService.java)
- 디렉토리 계층 구조 (예:
src/main/java/... 또는 src/components/...)
3. 대표적인 컨벤션 사례
많은 기업과 커뮤니티에서는 이미 검증된 표준 가이드라인을 제공하고 있으며, 대부분의 팀은 이를 기반으로 팀의 특성에 맞게 수정하여 사용한다.
- PEP 8 (Python): 파이썬 공식 스타일 가이드로, 들여쓰기 4칸 사용과 snake_case 명명법을 강조한다.
- Google Java Style Guide: 구글에서 사용하는 자바 코딩 표준으로, 매우 엄격한 포맷팅 규칙을 제공한다.
- Airbnb JavaScript Style Guide: 자바스크립트 커뮤니티에서 가장 널리 쓰이는 가이드 중 하나로, 최신 ES6+ 문법의 권장 사용법을 상세히 다룬다.
- Microsoft C# Coding Conventions: .NET 생태계의 표준으로, PascalCase의 광범위한 사용을 특징으로 한다.
4. 자동화 도구 및 적용 방법
수동으로 모든 컨벤션을 검토하는 것은 비효율적이며 휴먼 에러가 발생하기 쉽다. 이를 해결하기 위해 린터와 포매터를 도입한다.
린터는 코드의 질적 분석(논리적 오류, 잠재적 버그)에 집중하고, 포매터는 외형적 스타일(공백, 줄바꿈)에 집중한다.
| 구분 |
린터 (Linter) |
포매터 (Formatter) |
| 주요 목적 |
코드 품질 개선 및 버그 예방 |
코드 스타일의 일관성 유지 |
| 분석 대상 |
사용하지 않는 변수, 타입 오류, 위험한 문법 |
들여쓰기, 따옴표 종류, 줄바꿈 위치 |
| 수정 방식 |
경고(Warning) 또는 에러(Error) 발생 |
코드를 자동으로 재작성(Rewrite) |
| 대표 도구 |
ESLint, Pylint, Checkstyle |
Prettier, Black, clang-format |
4.2 설정 파일 예시
자동화 도구는 설정 파일을 통해 팀원 모두가 동일한 규칙을 적용받게 한다.
.prettierrc (JavaScript 포매터 설정 예시)
{
"semi": true,
"singleQuote": true,
"tabWidth": 2,
"trailingComma": "es5",
"printWidth": 80
}
컨벤션 준수를 강제하기 위해 다음과 같은 단계적 프로세스를 구축한다.
- 로컬 단계 (Pre-commit):
husky와 lint-staged를 사용하여 git commit 시점에 변경된 파일만 린트/포맷팅을 수행한다. 규칙을 통과하지 못하면 커밋이 자동으로 거부되어 잘못된 코드가 저장소에 올라가는 것을 원천 차단한다.
- 검증 단계 (Pull Request): GitHub Actions, Jenkins 등의 CI 도구에서 PR 생성 시 자동으로 린트 체크 스크립트를 실행한다.
- 차단 단계 (Merge Guard): CI 체크 결과가 'Fail'일 경우, Merge 버튼을 비활성화하여 컨벤션을 준수한 코드만 메인 브랜치에 병합되도록 강제한다.
5. 컨벤션 수립 및 운영 가이드
5.1 컨벤션 위반 사례 및 수정
잘못된 컨벤션 적용은 코드의 가독성을 떨어뜨리고 오해를 불러일으킨다.
[수정 전: 컨벤션 미준수 코드]
// 변수명 모호, 들여쓰기 불일치, 일관성 없는 따옴표 사용
function calculate(a,b){
let Result = a+b;
if(Result > 10){
console.log("Value is too high")
}
return Result
}
[수정 후: 컨벤션 준수 코드]
/**
* 두 수의 합을 계산하고 임계값을 확인합니다.
*/
function calculateSum(firstValue, secondValue) {
const sum = firstValue + secondValue;
if (sum > 10) {
console.log('Value is too high');
}
return sum;
}
[주요 변경 사항]
- 변수명: Result (PascalCase) $\rightarrow$ sum (lowerCamelCase)
- 함수명: calculate (모호함) $\rightarrow$ calculateSum (명확함)
- 포맷팅: 들여쓰기 불일치 수정 및 연산자 주변 공백 추가
- 기타: let $\rightarrow$ const (불변성 확보), 따옴표 통일(' 사용)
5.2 수립 및 운영 프로세스
- 표준 가이드 선정: 처음부터 모든 규칙을 정하기보다 PEP 8, Airbnb 등 기존 표준을 먼저 채택한다.
- 팀 합의 및 커스터마이징: 표준 가이드 중 팀의 성격과 맞지 않는 부분(예: 탭 vs 스페이스)을 논의하여 결정한다.
- 점진적 적용: 기존의 거대한 레거시 코드에 한꺼번에 컨벤션을 적용하면 Git History(변경 이력)가 오염된다. 신규 파일부터 적용하거나, 모듈 단위로 점진적으로 리팩토링한다.
- 문서화: 결정된 규칙을
CONTRIBUTING.md 또는 위키 페이지에 명시하여 신규 입사자가 빠르게 적응할 수 있도록 한다.
- 지속적 업데이트: 언어의 버전이 올라가거나 더 효율적인 패턴이 발견되면 정기적인 코드 리뷰를 통해 컨벤션을 업데이트한다.
5.3 컨벤션 도입 시 갈등 해결법
개발자마다 선호하는 스타일이 다르므로 컨벤션 수립 과정에서 의견 충돌이 발생할 수 있다. 이를 해결하기 위한 가이드라인은 다음과 같다.
- 개인 취향보다 '일관성' 우선: "어떤 방식이 더 좋은가"보다 "어떤 방식이 더 일관된가"에 집중한다. 정답이 없는 스타일 논쟁은 빠르게 종결하고 하나로 통일하는 것이 중요하다.
- 근거 기반의 의사결정: 단순히 "내 스타일이다"가 아니라, 공식 문서, 업계 표준, 혹은 가독성 테스트 결과 등 객관적인 근거를 제시하여 합의를 도출한다.
- 자동화 도구에 위임: 논쟁이 길어지는 포맷팅 규칙은 Prettier와 같은 도구의 기본 설정을 따르기로 합의하여, 사람이 아닌 도구가 결정하게 함으로써 감정 소모를 줄인다.
- 예외 허용 범위 설정: 특수한 성능 최적화가 필요하거나 외부 라이브러리와의 호환성을 위해 규칙을 어겨야 하는 경우, 주석으로 사유를 명시하고 팀의 승인을 받는 '예외 처리 프로세스'를 운영한다.
# 코딩 컨벤션 (Coding Convention)
## 1. 개요
**코딩 컨벤션(Coding Convention)**이란 소프트웨어 개발 시 코드의 가독성을 높이고 유지보수를 용이하게 하기 위해 개발자 간에 약속한 일관된 코드 작성 규칙의 집합을 의미한다.
현대의 소프트웨어 개발은 단독 작업보다는 팀 단위의 협업으로 이루어지는 경우가 많다. 개발자마다 선호하는 작성 스타일이 다를 경우, 동일한 로직이라도 표현 방식이 달라져 코드 리뷰 시간이 늘어나고 버그를 발견하기 어려워지는 문제가 발생한다. 따라서 일관된 코딩 컨벤션을 적용함으로써 '누가 작성했든 마치 한 사람이 작성한 것과 같은' 상태를 유지하는 것이 협업 효율성 극대화의 핵심이다.
## 2. 주요 구성 요소
코딩 컨벤션은 단순히 띄어쓰기를 맞추는 것을 넘어, 코드의 구조와 의미 전달 방식을 규정하는 다양한 항목을 포함한다.
### 2.1 명명 규칙 (Naming Convention)
식별자(변수, 함수, 클래스 등)의 이름을 짓는 규칙이다. 가장 널리 쓰이는 방식은 다음과 같다.
- **lowerCamelCase**: 첫 단어는 소문자로 시작하고 이후 단어의 첫 글자를 대문자로 표기 (예: `userName`)
- **PascalCase (UpperCamelCase)**: 모든 단어의 첫 글자를 대문자로 표기 (예: `UserAccount`)
- **snake_case**: 모든 글자를 소문자로 쓰고 단어 사이를 언더바(`_`)로 연결 (예: `user_name`)
- **kebab-case**: 모든 글자를 소문자로 쓰고 단어 사이를 하이픈(`-`)으로 연결 (예: `user-name`)
- **SCREAMING_SNAKE_CASE**: 모든 글자를 대문자로 쓰고 단어 사이를 언더바(`_`)로 연결 (예: `MAX_RETRY_COUNT`)
**[언어별 일반적인 명명 규칙 비교]**
| 대상 | Java | Python | JavaScript | C# |
| :--- | :--- | :--- | :--- | :--- |
| **클래스** | PascalCase | PascalCase | PascalCase | PascalCase |
| **변수/필드** | camelCase | snake_case | camelCase | camelCase |
| **함수/메서드** | camelCase | snake_case | camelCase | PascalCase |
| **상수** | SCREAMING_SNAKE | SCREAMING_SNAKE | SCREAMING_SNAKE | PascalCase |
### 2.2 들여쓰기 및 공백 (Indentation & Whitespace)
- **들여쓰기**: 탭(Tab)을 사용할지, 공백(Space) 2칸 또는 4칸을 사용할지 결정한다.
- **공백**: 연산자 주변의 공백(`a+b` → `a + b`), 괄호 안쪽의 공백 여부 등을 규정한다.
### 2.3 주석 작성법 (Commenting)
- **문서화 주석**: API나 클래스의 역할을 설명하는 Javadoc, TSDoc 등의 표준 형식 사용.
- **인라인 주석**: 복잡한 로직에 대해 '왜(Why)' 이렇게 작성했는지를 설명하는 주석 작성.
### 2.4 파일 및 폴더 구조
- 파일명 명명 규칙 (예: `user.controller.ts` 또는 `UserService.java`)
- 디렉토리 계층 구조 (예: `src/main/java/...` 또는 `src/components/...`)
## 3. 대표적인 컨벤션 사례
많은 기업과 커뮤니티에서는 이미 검증된 표준 가이드라인을 제공하고 있으며, 대부분의 팀은 이를 기반으로 팀의 특성에 맞게 수정하여 사용한다.
- **PEP 8 (Python)**: 파이썬 공식 스타일 가이드로, 들여쓰기 4칸 사용과 snake_case 명명법을 강조한다.
- **Google Java Style Guide**: 구글에서 사용하는 자바 코딩 표준으로, 매우 엄격한 포맷팅 규칙을 제공한다.
- **Airbnb JavaScript Style Guide**: 자바스크립트 커뮤니티에서 가장 널리 쓰이는 가이드 중 하나로, 최신 ES6+ 문법의 권장 사용법을 상세히 다룬다.
- **Microsoft C# Coding Conventions**: .NET 생태계의 표준으로, PascalCase의 광범위한 사용을 특징으로 한다.
## 4. 자동화 도구 및 적용 방법
수동으로 모든 컨벤션을 검토하는 것은 비효율적이며 휴먼 에러가 발생하기 쉽다. 이를 해결하기 위해 린터와 포매터를 도입한다.
### 4.1 린터(Linter) vs 포매터(Formatter)
린터는 코드의 **질적 분석(논리적 오류, 잠재적 버그)**에 집중하고, 포매터는 **외형적 스타일(공백, 줄바꿈)**에 집중한다.
| 구분 | 린터 (Linter) | 포매터 (Formatter) |
| :--- | :--- | :--- |
| **주요 목적** | 코드 품질 개선 및 버그 예방 | 코드 스타일의 일관성 유지 |
| **분석 대상** | 사용하지 않는 변수, 타입 오류, 위험한 문법 | 들여쓰기, 따옴표 종류, 줄바꿈 위치 |
| **수정 방식** | 경고(Warning) 또는 에러(Error) 발생 | 코드를 자동으로 재작성(Rewrite) |
| **대표 도구** | ESLint, Pylint, Checkstyle | Prettier, Black, clang-format |
### 4.2 설정 파일 예시
자동화 도구는 설정 파일을 통해 팀원 모두가 동일한 규칙을 적용받게 한다.
**`.prettierrc` (JavaScript 포매터 설정 예시)**
```json
{
"semi": true,
"singleQuote": true,
"tabWidth": 2,
"trailingComma": "es5",
"printWidth": 80
}
```
### 4.3 CI/CD 파이프라인 통합
컨벤션 준수를 강제하기 위해 다음과 같은 단계적 프로세스를 구축한다.
1. **로컬 단계 (Pre-commit)**: `husky`와 `lint-staged`를 사용하여 `git commit` 시점에 변경된 파일만 린트/포맷팅을 수행한다. 규칙을 통과하지 못하면 커밋이 자동으로 거부되어 잘못된 코드가 저장소에 올라가는 것을 원천 차단한다.
2. **검증 단계 (Pull Request)**: GitHub Actions, Jenkins 등의 CI 도구에서 PR 생성 시 자동으로 린트 체크 스크립트를 실행한다.
3. **차단 단계 (Merge Guard)**: CI 체크 결과가 'Fail'일 경우, Merge 버튼을 비활성화하여 컨벤션을 준수한 코드만 메인 브랜치에 병합되도록 강제한다.
## 5. 컨벤션 수립 및 운영 가이드
### 5.1 컨벤션 위반 사례 및 수정
잘못된 컨벤션 적용은 코드의 가독성을 떨어뜨리고 오해를 불러일으킨다.
**[수정 전: 컨벤션 미준수 코드]**
```javascript
// 변수명 모호, 들여쓰기 불일치, 일관성 없는 따옴표 사용
function calculate(a,b){
let Result = a+b;
if(Result > 10){
console.log("Value is too high")
}
return Result
}
```
**[수정 후: 컨벤션 준수 코드]**
```javascript
/**
* 두 수의 합을 계산하고 임계값을 확인합니다.
*/
function calculateSum(firstValue, secondValue) {
const sum = firstValue + secondValue;
if (sum > 10) {
console.log('Value is too high');
}
return sum;
}
```
**[주요 변경 사항]**
- **변수명**: `Result` (PascalCase) $\rightarrow$ `sum` (lowerCamelCase)
- **함수명**: `calculate` (모호함) $\rightarrow$ `calculateSum` (명확함)
- **포맷팅**: 들여쓰기 불일치 수정 및 연산자 주변 공백 추가
- **기타**: `let` $\rightarrow$ `const` (불변성 확보), 따옴표 통일(`'` 사용)
### 5.2 수립 및 운영 프로세스
1. **표준 가이드 선정**: 처음부터 모든 규칙을 정하기보다 PEP 8, Airbnb 등 기존 표준을 먼저 채택한다.
2. **팀 합의 및 커스터마이징**: 표준 가이드 중 팀의 성격과 맞지 않는 부분(예: 탭 vs 스페이스)을 논의하여 결정한다.
3. **점진적 적용**: 기존의 거대한 레거시 코드에 한꺼번에 컨벤션을 적용하면 Git History(변경 이력)가 오염된다. 신규 파일부터 적용하거나, 모듈 단위로 점진적으로 리팩토링한다.
4. **문서화**: 결정된 규칙을 `CONTRIBUTING.md` 또는 위키 페이지에 명시하여 신규 입사자가 빠르게 적응할 수 있도록 한다.
5. **지속적 업데이트**: 언어의 버전이 올라가거나 더 효율적인 패턴이 발견되면 정기적인 코드 리뷰를 통해 컨벤션을 업데이트한다.
### 5.3 컨벤션 도입 시 갈등 해결법
개발자마다 선호하는 스타일이 다르므로 컨벤션 수립 과정에서 의견 충돌이 발생할 수 있다. 이를 해결하기 위한 가이드라인은 다음과 같다.
- **개인 취향보다 '일관성' 우선**: "어떤 방식이 더 좋은가"보다 "어떤 방식이 더 일관된가"에 집중한다. 정답이 없는 스타일 논쟁은 빠르게 종결하고 하나로 통일하는 것이 중요하다.
- **근거 기반의 의사결정**: 단순히 "내 스타일이다"가 아니라, 공식 문서, 업계 표준, 혹은 가독성 테스트 결과 등 객관적인 근거를 제시하여 합의를 도출한다.
- **자동화 도구에 위임**: 논쟁이 길어지는 포맷팅 규칙은 Prettier와 같은 도구의 기본 설정을 따르기로 합의하여, 사람이 아닌 도구가 결정하게 함으로써 감정 소모를 줄인다.
- **예외 허용 범위 설정**: 특수한 성능 최적화가 필요하거나 외부 라이브러리와의 호환성을 위해 규칙을 어겨야 하는 경우, 주석으로 사유를 명시하고 팀의 승인을 받는 '예외 처리 프로세스'를 운영한다.