[코드프레소 체험단] SW 유지보수성 향상을 위한 Clean Code

Dev_Sanizzang·2022년 1월 23일
0

코드프레소 체험단

목록 보기
6/10

이 글은 코드프레소 Java 웹 개발 체험단 활동 중 SW 유지보수성 향상을 위한 Clean Code 강좌를 기반으로 작성하였습니다.


코드프레소 URL: https://www.codepresso.kr/

강의 목차


먼저 강의 목차는 아래 그림과 같이 구성되어 있습니다.

클린코드 소개


Clean Code?

클린코드란 이해하기 쉽고, 변경하기 쉬운 Code이다. 사람이 읽고 이해하기 쉽고, 명확한 한가지 역할을 하며, 이 역할을 의미 있게 표현하고, 중복이 없고 테스트 케이스가 존재하는 코드를 말한다.

Clean Code가 중요한 이유?

SW는 한번 신규 개발이 되고, 오랜 기간동안 유지보수가 된다. 기존 코드에 추가 작업하는 시간이 압도적으로 많으며, 대부분의 시간을 기존 코드를 읽고, 이해하는 데 사용하기 때문에 Clean Code가 중요하다. Code의 품질이 낮아지면 Code를 읽고 이해하는 데 더 많은 시간이 걸린다. 복잡도가 상승하여 코드를 수정하는 데 더 많은 시간이 걸리고, 테스트 코드가 없어서, 하나를 수정하면 여러 곳에서 Side-effect가 발생하여 결과적으로 개인과 조직 모두에게 커다란 비효율을 발생시킬 수 있다. 코드를 Clean하게 작성하면 퇴근 시간을 빠르게 만들어주고 집에 가서도 회사 전화를 받지 않게 해준다. 하지만 Clean Code를 위한 공식과 정답은 없다.

Clean Naming


Clean Naming

우리는 개발의 약 75%의 시간을 코드를 읽고 이해하는데 사용한다. 변수, 상수, 함수, 클래스, 파일 등 SW의 주요 요소는 이름을 갖고 있다. 좋은 이름은 내부를 들여다보지 않아도 동작과 목적을 쉽게 이해할 수 있다. 좋은 이름을 사용하면 코드를 읽는 사람의 인지적 부하를 최소화 할 수 있다.

Quora의 Ubuntu Forum의 설문 결과 프로그래머의 가장 어려운 Task로 Naming이 49%로 압도적인 결과를 나타냈다.
개발의 대부분은 코드를 이해하고 수정하는 행위이다. 수십, 수백만 라인의 코드를 읽고 이해하고 수정하는 것은 매우 어려운 일이다. Clean Naming에 대한 작은 투자는 장기적으로는 팀의 개발 생산성 향상에 크게 기여한다.

Clean Naming 원칙

Clean Naming 대원칙
모든 이름은 반드시 그 의미가 명확해야 한다 (모두에게)

Function, Class 역할이 명확하면 Naming도 명확해 진다. 불필요한 정보와 반복은 제거해야 하며 줄임말(약어)를 사용하면 안된다. 규칙과 일관성이 중요하며 동료와의 상의가 필요하다.

Clean Function, Class의 제 1원칙
명확히 한 가지 역할을 하자

역할이 많으면 이름도 명확하지 않게 된다.
ex) createAndSaveUserInfo(), User, GeneralUtil
명확한 이름을 짓기 어려울 때는 너무 많은 역할을 하고 있는게 아닌지 고민을 해봐야 한다.

Clean Function, Class의 제 2원칙
불필요한 정보/반복은 제거하자

이름은 이해가능한 최소한의 정보를 담고 있어야 한다.

Clean Function, Class의 제 3원칙
줄임말(약어)를 사용하지 말자

줄임말은 가독성을 심각하게 저하 시킨다. 누구나 이해할 수 있는 줄임말은 존재하지 않는다. 나에게 당연한 줄임말이 타인에게는 당연하지 않을 수 있다는 것을 인지해야한다.

  • 줄임말의 예
    ex)
    temp, prdt usr -> temperature, product, user
    acc(), inc() -> accelerateSpeed(), increasePrice()

Clean Function, Class의 제 4원칙
규칙과 일관성은 중요하다.

언어 별, 조직 별 Naming Convention을 일관성 있게 지켜야 한다. 일관성은 코드를 이해하고 수정하는 노력을 감소 시킨다. 일관성 없는 Naming은 가독성을 저하 시킨다. 그러므로 공식 Guide를 조직에 맞게 커스터마이징 하여 내부 Guide를 결정해야 한다. 결정 된 Guide를 잘 지키고, 이견이 있을 시 공론화가 필요하다. 코드 리뷰 시 Naming등이 Guide를 잘 지키고 있는지 반드시 확인해야 한다.

Variable를 위한 Clean Naming

Method를 위한 Clean Naming

Method의 이름은 의도와 기능을 명확하게 표현해야 한다. 만약 Method의 의도와 기능을 이해하기 위해 내부 코드를 들여봐야 한다면 그 Method의 이름은 개선 해야 될 필요가 있다. Method의 이름은 어떤 동작(동사)을 무엇을 대상(명사)으로 할 것인지로 표현 한다.

Clean Method?

좋은 Method는 작고, 한 가지 일만 수행한다. 작고, 한 가지 일만 수행하는 Clean Method는 Clean Name을 짓기가 쉽다. Method 이름을 정하기 어렵다면, Method가 Clean한지를 먼저 고민해봐야 된다.


Class를 위한 Clean Naming

클래스의 의해 생성되는 객체를 의미 있게 설명해야한다. Class가 명확한 한 가지 책임을 갖고 있다면, 명확한 이름을 짓기가 좋다. 명사 또는 명사구를 사용하고, 동사는 사용하지 않는다.

Clean Class Naming Principle
구체적이고 명확한 이름을 사용하라
Convention을 준수하는 일관성 있는 이름을 사용하라
보편 언어를 활용하라

구체적이고 명확한 이름

Convention을 준수하는 일관성 있는 이름

보편 언어

SW은 요구사항도출 -> 분석 -> 설계 -> 구현 -> 테스트의 반복적인 사이클이다. 요구사항 단계에서의 도메인 전무가의 멘탈 모델과 이를 구현하는 엔지니어의 멘탈 모델 사이의 커다란 Gap이 존재하는데 이는 유지보서성 낮은 SW가 만들어지는 원인이 된다.
이를 위해 엔지니어는 복잡한 현실의 문제(도메인)을 잘 파악한 후 설계와 코드에 반영해야 한다.

Coding Rule

Coding Rule의 종류

Coding Rule의 준수 여부 확인

Summary: Clean Naming

SW 엔지니어는 Code를 읽고 이해하고 수정하는 데 대부분의 시간을 사용한다. SW 유지보수를 효율적으로 하기 위해서는 높은 가독성이 필수적이다. 이해하기 쉬운 좋은 이름은 읽는 사람의 인지적 부하를 최소화 시킨다.

Clean Method


Clean Method

Method/Function은 SW에서 가장 기본이 되는 모듈이다. Method를 호출하는 사람이 사용하기 용이해야하며 유지보수하는 사람이 이해하고, 변경하기 용이해야 한다. Method를 유지보수 하는 사람이 테스트하기 용이해야 한다.

Clean Methods Principles

  • 가능한 한 충분히 작아야 한다
  • 한 가지를 해야 한다. 그 한 가지를 잘 해야 한다
  • 테스트 가능해야 한다
  • 중복이 없어야 한다

Parameter와 Clean Method

Parameter 원칙

  • Method를 호출하는 사람의 인지적 부하를 최소로 만들어 주어야 한다.
  • Method를 호출할 때마다 내부 코드를 보거나 API 문서를 보지 않게끔 해야 함
  • Parameter의 개수는 가능한 한 적어야 함

Clean Method의 크기

작고 역할이 명확한 메소드는 읽고 이해하기 용이하고 기존 코드를 수정하기 용히하다. 또한 단위 테스트하기 용이하며 재사용성이 높다.

한 가지의 명확한 역할

한 가지의 명확한 일을 하는 Method는 명확한 Naming이 가능하고, 이름만으로 기능을 이해할 수 있다. 복잡도가 낮아질 가능성이 높다. Mehod의 내부 코드를 이해하고 수정하기 용이하며 다누이 테스트하기 용이하다.

하나의 Method는 동일한 추상화의 수준만 가져야 한다


옳은 예

나쁜 예

Method의 이름이 책임지는 범위의 일만 해야 한다

옳은 예

나쁜 예

중복 코드

중복 코드란 일정 라인 수 이상이 다수 중복되어 존재하는 코드이다. 개발자는 복사/붙여넣기의 유혹과 갈등하는 경우가 있는데, 이런 중복 코드는 다양한 문제점을 발생 시킨다.
불필요하게 코드 베이스를 크게 만들고 코드를 수정해야 할 때 중복 된 다수의 코드를 모두 수정해야 한다. 중복 코드에 잠재적 결함이 있을 시, 결함도 같이 중복 된다.
이러한 중복 코드를 발견하기 위해서는 첫 번째로 코드 리뷰를 하는 것이다. 하지만 수동으로 전체 SW 시스템의 중복을 다 발견하기는 쉽지 않는데 이를 위한 정적 분석이라는게 있다. 이는 중복 코드를 찾아내는 정적 분석 도구를 활용하는 것인데, 그 도구로는 CPD와 Atomiq - Code Similartity Finder가 있다.

Clean Comment


Comment는 Code에 대한 사람이 읽을 수 있는 부가 설명이다. 사람이 Code를 더 쉽게 이해할 수 있게 하는 것이 목적이며, 일반적으로 Compiler/Interpreter는 Comment를 실행하지 않고 무시한다.

Clean Comment Principle

  • Comment는 필요악이다
  • Comment는 대부분의 상황에서 사용하지 말아야 한다
  • 그러나 Comment를 사용해야 하는 몇 가지 예외 상황이 있다

Comment로 부가 설명이 필요하면 Code가 충분히 의미 있지 못하다는 것이다. 의미 있는 이름, 명확한 Code는 어렵고, Comment는 쉽다. Comment에 의지하기 보다 의미 있는 Code를 작성하는 노력이 필요하다.

Bad Comment

  • 의미가 모호한 코드를 설명하는 Comment
  • 중복된 정보를 나타내거나 의무적으로 작성하는 Comment
  • Comment 처리 된 Code
  • 이력은 남겨놓은 Comment

    99%의 Comment는 불필요하다.
    다양한 Bad Comment의 유형이 있는데, 기억해야 할 1 가지는 Comment는 Code Bad Smell이다.

Clean Comment

Comment를 사용하지 않는 것이 최고의 Clean Comment이다. 진실은 오직 Code에만 존재하며 Code로 의미를 표현해야 한다.

  • 저작권 등을 명시하는 Comment
    - 회사의 정책에 의해 소유권, 저작권 등을 표시해야 하는 경우가 있다.
    • 모든 소스 파일에 저작권 표시 Comment가 필요하다.
  • 다수가 사용하는 Open API의 문서화
  • 이름만으로 충분히 의미를 전달하기 어려운 경우
    - 최대한 이름으로 의미를 표현해야 한다.
    • 불가피하게 이름만으로 충분히 의미/의도를 표현하지 못하는 경우
    • 대표적인 사례로 복잡한 정규표현식의 의도 표현이 있다.
  • TO DO Comment

Clean Formatting


Code Formatting은 코드의 가독성과 이해도를 높여주는 일련의 작업이다. 수직적 Formatting 원칙과 수평적 Formatting 원칙으로 분류된다.

문학적 프로그래밍

Donald Knuth에 의해 주창된 개념으로 코드는 사람이 읽도록 만들어지는 것이 우선이다. 문학 작품을 읽는 것처럼 코드를 읽을 수 있도록 만들어져야 하며 프로그래밍이란 컴퓨터가 어떤 동작을 하기 원하는지 "사람에게 설명"하는 행이다.

수직적(Vertical) Formatting

코드의 위에서 아래로 진행된 흐름과 관련 된 코드 작성 규칙으로 코드 라인간의 간격, 밀접한 관계를 가지는 코드 간 그룹화 등 이 포함된다.,

수평적(Horizontal) Formatting

하나의 코드 행에서 왼쪽에서 오른쪽으로 진행된 흐름과 관련 된 코드 작성 규칙으로 들여쓰기, 코드 간 간격, 코드 행의 넓이 등이 포함된다.

수직적 Formatting 원칙


수직적 Formatting은 Enter 같은 개행 문자를 이용해 Formatting 하는 것을 의미한다. 마치 신문기사처럼 위에서 아래 쉽게 읽혀 나갈 수 있는 것을 목표로 한다.

추상화의 수준 순서로 코드를 배치

서로 다른 개념은 분리

유사한 개념은 모아 놓음

수평적 Formatting 원칙

수평적 Formatting은 코드 한 줄에 대해서 Formatting 하는 것을 의미한다. 좌우 횡스크롤링 없이 코드를 읽을 수 있어야 하며 코드 한 줄을 스크롤의 이동없이 볼 수 있는 것을 목표로 한다.(약 80자)

Clean Control Structures


Control Structures 란?
조건, 루프(loop), 흐름을 제어하는 선언문

Cyclomatic Complexity

  • 소스 코드의 복잡도를 나타내는 지표
  • 1976년 Thomas J. McCabe에 의해 고안
  • 복잡도가 낮을수록 프로그램이 구조적으로 안정되었다는 의미이며,
  • 복잡도가 높을수록 프로그램이 비 구조적이며 불안정하다는 의미
  • 프로그램의 제어 흐름을 node, edge로 표현한 그래프를 기반으로 계산

읽기 쉬운 조건문

매직 넘버와 가독성

매직 넘버란, 그 의미를 알 수 없는 임의의 수를 말한다. 조건문에서의 매직 넘버는 코드의 가독성을 해치는 주요 원인으로 코드를 이해하기 위해 별도의 문서와 시간이 필요하다.

조건문을 구성하는 오른쪽 항의 값은 잘 설명할 수 있는 명확한 상수로 설계되어야 한다.

삼항 연산자와 가독성

삼항연산자를 사용하려면 항산 가독성을 고려해야 한다. 코드의 라인을 최소화하는 것 보다, 코드를 이해하는 시간을 최소화하는 것이 중요하다.

Fail Fast! Early Return!

핵심 로직을 처리 하기 전에 다수의 사전 검증 로직이 필요한 경우 사전 검증 로직과 핵심 로직이 혼재되어 코드의 가독성이 낮아질 수 있다.
이를 대비하기 위해서 검증 영역과 핵심 로직 영역을 분리시키면 Method의 복잡도가 낮아져 가독성이 향상되고, 테스트가 용이해진다.

Fail Fast란?
빨리 실패하는 '검증로직'을 다시 method로 분리하고 예외를 사용하면 코드의 가독성은 더욱 높이고, 복잡도는 낮출 수 있다.

최대한 긍정 조건으로 표현하라

긍정적인 표현은 부정적 표현보다 이해하기 상대적으로 용이하므로, 조건문은 긍정 표현을 사용하는 것이 가독성 관점에서 좋다.

Clean Code를 위한 Code Refactoring


Code Refactoring의 개념

SW 품질 향상을 목적으로 기능의 변경 없이, 내부 코드를 변경하는 기술로 2000년에 Martin Fowler가 소개하였다.
Refactoring의 철한은 티끌 모아 태산으로 기존 기능에 변경을 가하지 않는 수준의 아주 작은 코드 개선 작업니다. 하나 하나의 Refactoring은 너무 작아서 큰 의미가 없지만 작은 개선이 쌓이면 의미 있는 품질 향상이 가능하다.

profile
기록을 통해 성장합니다.

0개의 댓글