요약
- “좋은 코드를 만드는 체계적 방법”
- 코딩 표준으로 일관성을 확보하고,
- 명명 규칙·주석·시큐어 코딩으로 가독성과 안전성을 높이며,
- 리팩토링으로 코드 스멜을 제거해 구조를 개선하고,
- 인스펙션·정적 분석·TDD·페어 프로그래밍으로 품질을 검증하는
- 이 모든 활동이 결국 소프트웨어 품질로 귀결됩니다.
0. 코딩 로드맵
-
소프트웨어 제품의 품질은 결국 원시 코드(source code)에 모두 귀결된다.
- 설계가 완료되면 코딩 단계가 시작되는데,
- 코딩에 투입되는 시간은 다른 단계보다 상대적으로 적지만 품질에 미치는 영향은 매우 크다.
-
코딩 작업 로드맵
- 코딩 표준 정의 → 메서드 구현 → 클래스 인스펙션 → 단위 테스트 → 통합을 위한 릴리스
-
참고
- TIOBE 인덱스(2026년 5월) 기준 인기 프로그래밍 언어는 Python(1위), C(2위), Java(3위), C++(4위), C# 순이다.
1. 코딩 작업
-
목표
- 설계 명세에 따라 요구를 만족하는,
- 오류가 적은 품질 좋은 프로그램을 만드는 것
-
작업 과정
- 코딩 표준 작성 (원시코드를 같은 스타일로 통일)
- 프레임워크/응용 패키지 결정
- 클래스 구현 후 인스펙션
- 클래스 단위 테스트
- 응용 시스템으로 통합
-
자주 발생하는 오류
- 메모리 누수, 중복 Free 선언, NULL 사용, 별칭 남용
- 배열 인덱스 오류, 수식 예외(0으로 나누기), 하나 차이 오류(off-by-one)
- 스트링 처리 오류, 버퍼 오류
- 동기화 오류: 데드락(자원 점유), 레이스 컨디션(실행 순서 의존), 모순 있는 동기화(로킹/언로킹 문제)
2. 코딩 표준
2.1. 좋은 코딩 스타일
- 읽기 쉬움: 의미 있는 변수명, 적절한 들여쓰기
- 간결함: 복잡하지 않고 명확함, 중복 회피
- 코드의 간결함은 설계 품질에 좌우 (높은 응집력, 낮은 결합도)
2.2. 명명 규칙
| 대상 | 규칙 | 예시 |
|---|---|---|
| 변수/메서드 | 카멜 케이스 (소문자 시작) | thisIsAnExample |
| 상수 | 모두 대문자 | SPEED_OF_LIGHT |
| 클래스/인터페이스 | 파스칼 케이스 (명사, 대문자 시작) | FishBowl |
| 메서드 | 동사구 | setTitle(), getTitle() |
| 부울 함수 | ”is”로 시작 | isEquilateralTriangle() |
| 패키지 | 모두 소문자, 명사 |
- 변수 이름 가이드
- 매개변수는 짧게, 필드 변수는 길고 의미 있게
2.3. 헝가리안 표기법
- 변수 이름 앞에 타입을 표시
lAccountNum(long),strName(string),szName(\0 종료 스트링) 등
2.4. 주석
- 다른 사람이 이해하기 쉽도록 작성, 디버깅 도움
- 불필요한 단어 생략, 과도한 주석 피하기
- 클래스 불변조건, 메서드 주석(Javadoc -
@param,@return), 클래스 주석(용도/저자/수정일), 문장 주석 활용
2.5. 시큐어 코딩
-
2012년 행정안전부 발표로 의무화된 기법으로,
-
구현 단계에서 보안 취약점을 사전 제거하여 외부 공격으로부터 안전한 SW를 개발하는 프로그래밍 기법이다.
-
예) SQL Injection 방지를 위해
Statement대신PreparedStatement+ 바인딩 변수 사용 -
SEI CERT 코딩 표준
- 카네기멜론 대학 SEI에서 발행하는 국제 코딩 표준으로 Android, C, C++, Java, Perl 지원
3. 설계에서 코드 생성
- IDE 도구가 UML 다이어그램으로부터 원시코드 골격을 자동 생성한다.
- 연관 관계는 1대1, 1대N, N대N으로 코딩한다.
4. 리팩토링
4.1. 정의 및 목적
-
리팩토링: 겉으로 보이는 동작의 변화 없이 내부 구조를 변경하여 이해와 수정이 쉽도록 만드는 작업
-
목적: 버그 식별 용이, 디자인/구조 개선, 가독성 향상, 생산성 향상
-
과정: 단일 리팩토링 → 테스트 → 작동하면 다음 단계, 안 되면 Undo
4.2. 코드 스멜 (Code Smell)
- 나쁜 코드의 징후로, 리팩토링이 필요함을 알려주는 신호이다.
주요 코드 스멜과 리팩토링 방법
| 코드 스멜 | 설명 | 해결 |
|---|---|---|
| 중복된 코드 | 코드/데이터 중복 | 중복 제거 |
| 긴 메서드 | 메서드가 너무 김 | 적정 크기로 분할 |
| 큰 클래스 | 속성/메서드 과다 | 클래스 분할 |
| 긴 파라미터 리스트 | 파라미터 과다 | 개수 축소 |
| Divergent Class | 여러 이유로 수정됨 | 단일 책임으로 변경 |
| Shotgun Surgery | 여러 클래스 동시 수정 | 한곳에 모음 |
| Feature Envy | 다른 클래스 데이터 자주 사용 | 메서드 이동 |
| Data Clumps | 데이터 그룹 중복 | 독립 클래스로 |
| Primitive Obsession | 기본 타입만 사용 | 클래스로 묶음 |
| Switch/If 남용 | 과다한 case | 다형성으로 변환 |
| Lazy Class | 사용 빈도 낮음 | 제거/합병 |
| Message Chain | 객체 호출 체인 과다 | 직접 사용 |
| Middle Man | 책임을 다른 곳에 위임만 함 | 미들맨 제거 |
4.3. 주요 리팩토링 기법
-
메서드 추출(Extract Method)
- 코드 조각을 별도 메서드로
- (예: swap 함수 추출)
-
클래스 추출(Extract Class)
- 한 클래스가 두 가지 일을 하면 분할
- (예: Customer에서 Phone 분리)
-
서브클래스 추출(Extract SubClass)
- 일부 인스턴스만 쓰는 기능을 서브클래스로
- (예: Person → Employee)
-
메서드 이동(Move Method)
- 다른 클래스 기능을 더 많이 쓰면 이동 (응집도↑ 결합도↓)
-
인터페이스 추출(Extract Interface)
- 공통 부분집합을 인터페이스로
-
템플릿 메서드 형성(Form Template Method)
- 비슷한 메서드를 상위 클래스로 통합
5. 코드 품질 향상 기법
5.1. 코드 인스펙션 (Code Inspection)
- 프로그램을 읽어 눈으로 확인하는 엄격한 정적 테스트 기법
- 코드 리뷰보다 체계적/공식적
- 컴파일 및 정적 분석 후 진행, 체크리스트 활용
- 결함 타입: 로직 문제, 컴퓨팅 문제, 인터페이스/타이밍 문제, 데이터 처리 문제
5.2. 정적 분석 (Static Analysis)
- SW 도구로 원시 코드를 분석하여 취약점 발견 (코드 실행 없이)
| 용도 | 도구 |
|---|---|
| 코딩 스타일/일관성 | ESLint, CheckStyle, SpotBugs, Pylint, CppCheck |
| 버그/취약점 탐지 | SonarQube, FindBugs, Bandit, Coverity |
| 코드 복잡도 분석 | SonarQube, Radon, CodeClimate |
| 의존성/라이브러리 검사 | npm audit, Snyk, DepCheck |
5.3. 테스트 중심 개발 (TDD)
-
테스트 코드를 먼저 작성한 후 기능을 구현하는 방법으로, 주로 클래스 메서드를 시험한다.
-
TDD 사이클
- RED(테스트 케이스 작성) → GREEN(테스트 통과 최소코드) → REFACTOR(코드 수정 및 반복)
-
JUnit 같은 프레임워크로
@Test어노테이션과assertEquals등을 활용해 테스트를 작성한다.
5.4. 페어 프로그래밍 (Pair Programming)
-
애자일에서 많이 쓰는 방법으로, 두 명이 한 컴퓨터에서 함께 코딩하며 협업, 피드백, 코드 리뷰를 동시에 수행한다.
-
장점: 높은 코드 품질, 지식 공유, 빠른 문제 해결, 소통 향상
-
단점: 페어 간 충돌 가능성, 비효율적 대화로 인한 시간 지연