코드프레소 Java 웹 개발 체험단 활동 중 이번엔 SW 유지보수성 향상을 위한 Clean Code 강의를 수강했다.
Clean Code는 앞으로 실무와 프로젝트를 겪게 되면 가독성이 협업에서 굉장히 업무 효율성을 영향을 미치게 될 것이다.
이와 관련하여 Clean Code에 대해 포스팅을 하려 한다.
왜 Clean Code가 중요한가?
SW Lifecycle의 총 비용 중 SW 개발 비용은 7%, 유지보수 비용은 무려 64% 차지하는 통계를 확인했다.
개발하는 SW를 장기간 유지보수 해야 하는 상황
- 단순히 동작하는 코드를 빠르게 작성해야 하는 것
- 읽고 이해하기 쉬운 코드를 주의 깊고 세심하게 작성하는 것
Naming
A | B |
개발 속도를 위해 약어를 써야 한다. Manager와 같은 접미사 사용해야 한다. |
약어는 절대 사용하면 안되며, 반복적이고 불필요한 단어는 제거해야 된다. |
Comment
A | B |
최대한 상세히 주석을 적어야 한다. 코드 수정 이력 등도 주석에 적어야 한다. |
주석은 Bad Smell이다. 최소로 해야 하며 코드로 표현해야 한다. |
Method, Class의 크기
A | B |
너무 작고 많으면 유지보수하기가 힘들다. | 크기는 가능한 작고 역할은 명확해야 한다. |
중복 코드
A | B |
기존 코들를 빠르게 복사하면 개발 속도를 향상 시킬 수 있다. | 중복 코드는 무조건 제거되어야 한다. |
테스트 코드
A | B |
테스트 코드는 코드 기능에 영향을 미치지도 않고 공수가 너무 많이 드는 작업이다. | 중장기적인 유지보수성 향상을 위해서 테스트 코드는 필수이다. |
Clean Code의 공통적 의견
- 사람이 읽고 이해하기 쉽다.
- 단순한 한 가지 역할을 하고, 명확한 이름을 갖고 있다.
- 중복이 없다.
- 테스트 케이스가 있다.
Clean Code의 범위에 속하지 않는 것
- 자료구조/알고리즘
- SW의 성능 개선
- 신뢰성, 안정성을 위한 개발 기법
- SW 아키텍처 설계 기법
- 언어 별 Programming best Practice
Clean Code의 중요성
- SW는 한번 신규 개발되고, 오랜 기간동안 유지보수 된다.
- 기존 코드에 추가 작업하는 시간이 압도적으로 많다.
- 대부분의 시간을 기존 코드를 읽고, 이해하는 데에 사용
Code의 품질이 낮아지면
- Code를 읽고 이해하는 데 더 많은 시간이 걸린다.
- 복잡도가 상승하여 코드를 수정하는 데 더 많은 시간이 걸린다.
- 테스트 코드가 없어서, 하나를 수정하면 여러 곳에서 Side-effect가 발생된다.
Clean Variable Name
굳이 출력해보지 않아도 내부에 담겨 있는 데이터를 알 수 있음
Clean Function/Method Name
내부 코드를 들여다보지 않아도 동작을 예측할 수 있음
내부 코드를 이해하지 못해도 활용하는데 문제가 없음
Clean Class Name
이름만으로도 구체적으로 어떤 객체가 생성되는 지 파악 가능
Clean Naming 원칙
Function, Class 역할이 명확해지면 Naming도 명확
- 명확히 한 가지의 역할 수행
- 역할이 많으면 이름도 명확하지 않는다.
- 이름을 짓기 어려울 땐 한번 고민
불필요한 정보/반복은 제거
- 이름은 이해 가능한 최소한의 정보를 담고 있어야 한다.
- 불필요한 정보 예시로 UserData, processFunc()
줄임말을 사용X
- 줄임말은 가독성을 저하시킨다.
- 누구나 이해할 수 있는 줄임말은 존재하지 않는다.
규칙과 일관성은 중요
- 일관성은 코드를 이해하고 수정하는 노력을 감소시킨다.
- 일관성없는 Naming은 가독성을 저하시킨다.
- 공식 Guide를 조직에 맞게 커스텀마이징하여 내부 Guide를 결정
구체적인 원칙이나 프로세스는 동료(팀원)와 협의
- 모든 원칙을 적용해도 좋은 이름이 떠오르지 않을 때
- 내가 정한 이름에 대한 확신이 없을 때
- 함께 브레인스토밍하는 것이 가장 좋은 방법
Clean Method
- Method/Function은 SW에서 가장 기본이 되는 모듈
- Method를 호출하는 사람이 사용하기 용이해야 한다.
- Method를 유지보수 하는 사람이 이해하고, 변경하기 용이해야 한다.
- Method를 유지보수 하는 사람이 테스트하기 용이해야 한다.
Clean Method 원칙
- 가능한 한 충분히 작아야 한다.
- 한 가지를 해야 한다. 그 한 가지를 잘 해야 한다.
- 테스트 가능해야 한다.
- 중복이 없어야 한다.
Parmeter 원칙
- Method를 호출하는 사람의 인지적 부하를 최소로 만들어 주어야 한다.
- Method를 호출할 때마다 내부 코드를 보거나 API 문서를 보지 않게끔 해야 한다.
- Parameter의 개수는 가능한 한 적어야 한다.
Parameter의 개수가 3~4개 이상일 때
Method를 분할 | Method가 너무 많은 역할을 하고 있을 가능성 있다. 명확히 한 가지 역할을 하는 2개 이상의 Method로 분할 |
Parameter Object 사용 | Parameter Data를 저장하는 Object 활용 |
생성자의 경우 Builder Pattern을 활용 | Product("cleancode", "course", 10, "Yunbeom") Product.builder().name("cleancode").type("course").price(10).build(); |
Map의 사용 | Parameter 개수 많을 시 Map 사용의 유혹이 있음 Map의 Key 값이 유동적이기 때문에 추가적인 문서화 필요 Map의 Key의 정보나 개수가 변경되었을 시 알기 어려움 호출하는 사람이 Key값에 오타를 입력했을 경우 에러 발생 |
한 가지의 명확한 일을 하는 Method
- 명확한 Naming이 가능하고, 이름만으로 기능을 이해할 수 있다.
- 복잡도가 낮아질 가능성이 높음
- Method의 내부 코드를 이해하고 수정하기 용이
- 단위 테스트하기 용이
추상화의 수준
Clean Method의 지속적인 개선
한 가지를 잘하는 Method를 만드는 것은 어렵다.
조직 내 컨센서스를 만들어 나가야 한다. (코드 리뷰를 통해 메소드를 지속적으로 리뷰하고 개선)
충분히 작은 지, 테스트 되고 있는 지, 끊임없는 질문과 개선이 중요
처음부터 거대한 Method는 적다.
중복 코드
- 일정 라인 수 이상이 다수 중복되어 존재하는 코드
- 개발자는 복사/붙여넣기의 유혹과 갈등하는 경우가 있다.
- 기존 메소드/클래스를 수정하기는 두려운데 복사/붙여넣기를 해서 조금만 수정할까?
- 중복 코드는 다양한 문제점을 발생시킨다.
일부만 다른 코드 중복
- 코드의 중복은 되지만 중간 1~2 라인 정도는 다른 경우
- Refactoring 하기 가장 까다로운 유형
중복 코드의 문제점
- 불필요하게 코드 베이스를 크게 만듦
- 코드를 수정해야 할 때 중복된 다수의 코드를 모두 수정해야 한다. (일부 누락될 시 에러 발생 가능)
- 중복 코드에 잠재적 결함이 있을 시, 결함도 같이 중복된다.
중복 코드의 해결
- 다양한 리팩토링 전략 및 디자인 패턴 적용
- 중복된 코드를 새로운 Method로 추출
- 기존 중복 코드의 부분에서 새로운 Method를 호출
- 서로 다른 클래스에 코드가 중복될 경우, 중복 코드 부모 클래스에 위치시키고 기존 클래스들은 해당 클래스를 상속
비자아적 프로그래밍
- 엔지니어 개개인의 요소들을 최대한 제거함으로서 전체 SW 품질을 높이는 문화
- 각자 만든 코드에 개인의 자아를 투영하지 말아야 한다.
- 코드에 대한 공동소유, 공동 책임 철학을 강조해야 한다.
- 프로젝트 초기부터의 지속적인 코드 리뷰 또는 페어 프로그래밍으로 달성 가능하다.
Clean Comment
- Comment는 Code에 대한 사람이 읽을 수 있는 부가 설명
- 사람이 Code를 더 쉽게 이해할 수 있게 하는 것이 목적
- 일반적으로 Compiler/Interpreter는 Comment를 실행하지 않고 무시
Comment는 필요악
- Comment로 부가 설명이 필요하면 Code가 충분히 의미있지 못하다는 것
- 의미있는 이름, 명확한 Code는 어렵고, Comment는 쉬움
- Comment에 의지하기 보다 의미 있는 Code를 작성하는 노력이 필요
- Comment의 정보는 잘못되거나, 오래된 정보를 담고 있을 가능성이 높음
Bad Comment
- 의미가 분명한 Code에 Comment로 중복 설명
- 중복은 제거해야 마땅하다.
- Code 변경 시 Comment는 변경되지 않을 가능성도 존재
Todo Comment
- Todo Comment로 앞으로 해야할 작업을 간략히 표시 가능
- 주기적으로 Todo Comment 확인할 필요가 있다.
Clean Formatting
- Code Formatting은 코드의 가독성과 이해도를 높여주는 일련의 작업
- 수직적 Formatting 원칙과 수평적 Formatting 원칙으로 분류된다.
수직적 Formatting
- 코드의 위에서 아래로 진행된 흐름과 관련된 코드 작성 규칙
- 코드 라인간의 간격, 밀접한 관계를 가지는 코드 간 그룹화 등이 포함됨
수평적 Formatting
- 하나의 코드 행에서 왼쪽에서 오른쪽으로 진행된 흐름과 관련된 코드 작성 규칙
- 들여쓰기, 코드 간 간격, 코드 행의 넓이 등이 포함된다.
Clean Control Structures
- 조건, 루프, 흐름을 제어하는 선언문
- if, if-else, for, while, do while, ...
- Control Structures 는 코드 복잡도에 가장 큰 영향을 주는 요소
- 특히 중첩된 Control Structures는 코드의 가독성↓ 복잡도↑ 테스트 용이성↓
Cyclomatic Complextity
- 소스코드의 복잡도를 나타내는 지표
- 복잡도가 낮을 수록 프로그램이 구조적으로 안정되었다는 의미
- 복잡도가 높을 수록 프로그램이 비구조적으로 불안정하다는 의미
- 프로그램의 제어 흐름을 node, edge로 표현한 그래프를 기반으로 계산
Code Refactoring
- SW 품질 향상을 목적으로 기능의 변경 없이, 내부 코드를 변경하는 기술
- 기존 기능에 변경을 가하지 않는 수준의 아주 작은 코드 개선 작업
- 하나하나의 리팩토링은 너무 작아서 큰 의미가 없음
- 그러나 작은 개선이 쌓이면 의미있는 품질 향상이 가능
Code Bad Smell
- Clean 품질을 저해할 수 있는 가능성을 가진 코드가 보내는 경고 싸인
- Code Bad Smell은 결함이나 에러는 아니다.
- 지속적 코드 개선을 위해서는 Bad Smell을 맡을 수 있는 코가 필요하다.
코드프레소 URL: https://www.codepresso.kr/
프리미엄 IT 교육 서비스 - 코드프레소
www.codepresso.kr