본문 바로가기
코드프레소 체험단/Clean Code

[SW 유지보수성 향상을 위한 Clean Code] Clean Method

by 의정부핵꿀밤 2022. 1. 24.
728x90

✨ 이 글은 [ 코드프레소 Java 웹 개발 체험단 활동 ] 내용입니다 ✨

💜 코드프레소 이러닝 강의 수강 중 - SW 유지보수성 향상을 위한 Clean Code 💜

😎 아래의 링크를 통해 프리미엄 IT 교육 서비스, 코드프레소를 확인해보세요 😎

https://www.codepresso.kr/

 

프리미엄 IT 교육 서비스 - 코드프레소

 

www.codepresso.kr


Clean Method

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

 

 

Unix philosophy

https://dotadiw.com/

 

DOTADIW

 

dotadiw.com

  • DOTADIW : Do One Thing and Do It Well
  • 유닉스의 철학
  • 각각의 모듈이 하나만 하고, 그 하나를 잘 하도록 구현하여 유닉스 자체를 유지보수하기 쉽고 확장하기 쉽게 만들 수 있었다

 

 

Clean Methods Principles

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

Parameter 원칙

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

 

 

Parameter의 개수

  • 숫자의 집착할 필요도, 정답도 없지만 단순히 참고하기 좋은 몇가지 방법들이다

 

 

Parameter의 개수가 3-4개 이상일 때

  • Method를 분할한다
    • Method가 너무 많은 역할을 하고 있을 가능성이 있다
    •  명확히 한 가지 역할을 하는 2개 이상의 Method로 분할한다
  • Parameter Object를 사용한다
    • Parameter Data를 저장하는 Object를 활용한다
    • saveProduct(product) -> product : name, type, price, instructor ...
  • 생성자의 경우 Builder Pattern을 활용한다
    • Product("claencode", "course", 10, "Donghun", ...) -> Bad Smell
    • Prodect.builder().name("claencode").type("course"),price(10).build() 
  • Map의 사용 (비추천)
    • Parameter 개수가 많을 때 Map 사용의 유혹이 있다
    • Map의 Key 값이 유동적이기 때문에 추가적인 문서화가 필요하다
    • Map의 Key의 정보나 개수가 변경되었을 시 알기 어렵다
    • 호출하는 사람이 Key 값에 오타를 입력했을 경우 에러가 발생한다

 


작고 역할이 명확한 메소드?

  • 읽고 이해하기 용이하다
  • 기존 코드를 수정하기 용이하다
  • 단위 테스트하기 용이하다
  • 재사용성이 높다

 

 

적절한 Method의 크기

 

 

크기만으로 Method의 품질을 판단할 수는 없다

  • 크기가 작다고 무조건 좋은 메소드도 아니고, 크기가 크다고 무조건 나쁜 메소드는 아니다
  • 물론 메소드의 크기는 메소드의 품질을 측정하는 지표이지만, 무조건적인 기준이 될 수는 없다

 

 

중요한 것은 지속적인 개선이다!

  • 라인 수보다 중요한 것은 자신의 코드에 대한 끊임없는 질문과 개선이다
    • 이 함수를 동료가 쉽게 이해할 수 있을까?
    • 충분히 작은가? 더 작게 분할할 수 있는가?
    • 단위 테스트 코드에 의해 충분히 테스트되고 있는가?
    • 너무 많은 역할을 하고 있지는 않은가?

 

 

Kent Beck's Four Simple Design Rules

  • Extreme Programming, Junit의 창시자
  • TDD(Test Driven Development)의 선구자

이 분은 4가지의 규칙을 제시하였다!

  1. 모든 테스트를 실행해야 한다
  2. 중복을 없애야 한다
  3. 프로그래머의 의도를 잘 설명해야 한다
  4. 클래스와 메소드의 크기를 최소한으로 유지한다

 

 

Rule of Thumb - Method의 크기

명확한 지표나 기준은 아니지만, 대가들의 말을 종합했을 때 참고하면 좋은 기준들!

  • 10 ~ 100 라인 사이가 적절하지만, 숫자에 집착할 필요는 없다
  • 1개의 Method는 스크롤링을 하지 않고 읽을 수 있어야 한다
  • 단위 테스트 케이스를 작성하는 데 어려움이 없어야 한다
  • Method 동작을 설명하기 위해 내부에 주석을 달아야 하면 Bad Smell!
    • 주석이 필요한 코드들은 새로운 Method로 추출하는 게 좋다!

한 가지의 명확한 일을 하는 Method는?

  • 명확한 Naming이 가능하고, 이름만으로 기능을 이해할 수 있다
  • 복잡도가 낮아질 가능성이 높다(Cyclomatic Complexity)
    • 조건문의 복잡한 중첩구조가 적다
  • Method의 내부 코드를 이해하고 수정하기 용이하다
  • 단위 테스트하기가 용이하다

 

 

한 가지의 일이란 무엇인가?

  • 한 가지의일은 한다는 것이 정확히 어떤 의미인가?
  • Method마다 1라인의 코드만 있어야 하는 것인가?
  • 자 이제 아래에서 확인해보자!

 

 

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

  • 추상화의 수준(Level of Abstraction)이란?

  • 가장 높은 레벨은 비즈니스 적 측면에서의 기능을 얘기한다
  • 가장 낮은 레벨은 디테일한 HOW를 제공해주는 코드를 얘기한다
  • 그 사이에는 수많은 레벨이 존재하지만, 반드시 동일한 레벨 또한 존재한다

 

 

추상화의 수준

Higher Level vs Lower Level

 

 

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

 

 

 

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

 

 

 

이름의 책임을 벗어나는 Bad Smell

 

 

 

중요한 것은 지속적인 개선

  • 한 가지를 잘하는 Method를 만드는 것을 어렵다
  • 조직 내 컨센서스를 만들어 나가야 한다
  • 코드 리뷰를 통해 메소드를 지속적으로 리뷰하고 개선해야 한다
  • 끊임없는 질문과 개선이 중요하다
    • 충분히 작은가?
    • 충분히 테스트 되고 있는가?
  • 처음부터 거대한 Method는 적다
    • 설계를 고려하지 않고 기존 Method에 기능을 추가하는 것은 위험하다

 


중복 코드란?

  • 일정 라인 수 이상이 다수 중복되어 존재하는 코드
  • 개발자는 복사/붙여넣기의 유혹과 갈등하는 경우가 있다
  • 기존 메소드/클래스를 수정하기두려운데 복사/붙여넣기 해서 조금만 수정할까..? 라는 고민을 한다
  • 이러한 중복 코드는 다양한 문제점을 발생시킨다

 

 

중복 코드의 종류 - Method 전체 코드 중복

  • 다수의 Method의 구현부가 100% 일치
  • Method 이름은 다를 수 있다

 

 

중복 코드의 종류 - 연속된 일련의 코드 중복

  • Method 전체는 아니지만 일부 연속된 코드가 다수 중복됨
  • 중복 코드의 대다수를 차지하는 유형

 

 

 

중복 코드의 종류 - 일부만 다른 코드 중복

  • 코드가 중복되지만, 중간 1-2라인 정도만 다름
  • 이런 유형이 Refactoring하기 가장 까다로운 유형이다

 

 

 

중복 코드의 문제점

  • 불필요하게 코드 베이스를 크게 만든다 - 유지보수성이 떨어진다
  • 코드를 수정해야할 때 중복된 다수의 코드를 모두 수정해야 한다
    • 일부 누락될 시 에러가 발생할 가능성이 있다
    • 5개의 중복 코드 중 4개만 고치면 에러!
  • 중복 코드에 잠재절 결함이 있을 시, 결함도 같이 중복된다

 

 

중복 코드의 발견

  • 코드 리뷰
    • 지속적으로 코드 리뷰를 하게 되면 중복의 발견 가능성이 높아진다 
    • 하지만수동으로 전체 SW 시스템의 중복을 다 발견하기는 쉽지 않다
  • 정적 분석
    • 중복 코드를 찾아내는 정적 분석 도구를 활용한다
    • CPD
    • Atoi=miq - Code Similarity Finder

 

 

중복 코드의 해결

  • 다양한 Refactoring 전략 및 Design Pattern 적용
  • Extract Method
    • 중복된 코드를 새로운 Method로 추출한다
    • 기존 중복 코드의 부분에서 새로운 Method를 호출한다
  • Extract Superclass
    • 서로 다른 클래스에 코드가 중복될 경우
    • 중복 코드를 부모 클래스에 위치시키고, 기존 클래스들은 해당 클래스를 상속하도록 한다
    • 하지만 상속은 결합도 측면에서 안 좋을 수도 있으므로 주의해서 사용한다!
  • Template Method Pattern
    •  
    • 알고리즘의 일부가 중복되는 경우 사용 (중간의 몇 라인만 중복되는 경우)
    • 공통적인 알고리즘을 정의하고, 일부 다른 알고리즘을 상속받아서  오버라이딩하는 형태

 


SW Aging

  • SW도 사람처럼 늙으면서 여기저기 고장난다
  • 처음 SW가 설계되고 구현되었을 때가 가장 품질이 좋다
  • SW가 오래 유지보수될 수록 기술 부채가 늘어난다
    • 코드 품질 저하
    • 아키텍처 품질 저하
    • 실제 SW와 문서 간의 차이 발생
  • 기존 코드를 유지보수하는 비용이 더 커서 SW를 완전 재개발 해야 되는 상황이 발생한다

 

 

깨진 유리창 이론

  • 깨진 유리창을 방치하면 그 장소를 중심으로 범죄가 확산된다는 이론
  • 사소한 문제를 방치하면 빠르게 큰 문제로 번질 가능성이 높아진다

 

 

 

깨진 유리창 이론과 중복 코드

  • "쟤도 하는데 나도 해도 괜찮지 않을까..?" 라는 심리로 코드의 중복이 쌓이게 된다!

 

 

 

 

깨진 유리창 이론과 Long Method

  • 작고 명확하게 한 가지 일을 하는 Method는 수정할 때도 더 신경쓰게 된다
    • 내가 이 메소드의 품질을 낮추면 어쩌지...? 라는 마음으로 더 조심하게 됨
  • 그러나 200라인 Method에 10라인 추가하는 것은 죄책감이 들지 않는다
    • 심지어 클린 코드이 지식이 있어도 그렇다
    • "이미 긴 메소드에 내 코드 몇 줄 추가한다고 뭐 달라지겠어~?" 하는 마음

 

 

 

깨진 유리창 이론과 Clean Code

  • 깨진 창문이 일정 수준 이상 많아지면 개발자들은 자포자기한다
    • 나 혼자 노력하는 게 의미가 있나?
    • 나도 편하게 개발하자... 코드 돌아가기만 하면 됐지... 하는 마음
  • 창문을 깨지지 않게, 깨진 창문도 정상화는 조직 차원의 문화가 형성되어야 한다
    • 코드 품질에 대한 컨센서스를 맞춰야 하나다
    • 코드 리뷰, 정적 분석, 테스트 커버리지 확인
    • 지속적인 SW 품질 향상에 대한 노력이 가장 중요하다!

 


보이스카우트 법칙

  • 캠프장에 처음왔을 때보다 더 깨끗하게 해놓고 떠나라
  • 체크아웃 할 떄보다 조금이라도 더 깨끗한 코드를 체크인하라!
  • 아주 작은 개선일지라도 지속되면 코드는 더이상 나빠지지 않는다
    • 조금 긴 함수를 분할한다
    • 중복 코드를 제거한다
    • 복잡한 if 문 1개를 정리한다

 

 

보이스카우트 규칙의 전제

  • Clean Code를 장려하는 문화
    • 코드를 개선하는 노력을 무시해서는 안된다!
  • 단위 테스트 코드
    • 수정 후에는 항상 기존 기능에 영향이 없음을 검증해야 한다
    • 개발자가 수동으로 테스트 하는 것에는 한계가 있다
    • 수정 후에는 테스트 코드를 실행하여 문제가 없음을 확인한다

 

 

지속적인 코드 개선의 걸림돌

  • 엔지니어는 자신의 코드에 자신의 자아를 투영하는 경향이 있다
  • 자신이 작성한 코드에 과도한 애착을 갖고, 심각한 방어적 태도를 갖는 경우가 존재한다 (내 얘긴줄..ㅋㅋ)
  • 자신의 코드를 리뷰받고 피드백 하는 것에 대한 거부감을 갖는 경우가 있다
  • 자신의 코드를 다른 사람이 수정하는 것에 대한 거부감을 갖기도 한다

 

 

 

비자아적 프로그래밍(Egoless Programming)

  • 엔지니어 개개인의 요소들을 최대한 제거함으로써 전체 SW 품질을 높이는 문화
  • 각자 만든 코드에 개인의 자아를 투영하지 말아야 한다
  • 코드에 대한 공동 소유, 공동 책임 철학을 강조해야 한다
  • 프로젝트 초기부터의 지속적인 코드 리뷰 또는 페어 프로그래밍으로 달성 가능!
  • 처음부터 코드 리뷰에 대한 거부감과 코드에 대한 애착을 줄일 수 있는 방법이다!

 

 

 

비자아적 프로그래밍을 위한 가이드

  • The Ten Commandments of Egoless Programming - Jeff Atwood
  • 당신이 실수할 수 있다는 것을 받아 들여라
  • 당신과 당신이 작성한 코드는 다르다
  • 당신보다 지식이 적은 사람이라도 존중하고 인내를 갖고 대하라
  • 세상에 고정되어 있는 것은 없다. 변화를 받아들여라!
  • 사람이 아닌 코드를 비판하여라. 사람에게는 친절히 대하라.

 


Method 측정 지표

Lines Of Code

  • Method 의 길이를 측정한다
  • 조직에서 Bad Smell의 기준을 정하고 이를 넘는 Method를 검출한다
  • 기존 시스템의 Method들 LOC의 평균/표준편차 등을 측정한 후 Outlier를 검출한다

 

 

Cyclomatic Complexity

  • Method 내부의 복잡도를 측정하는 지표
  • Method 내부의 조건문 중첩이 복잡할 수록 높아진다
  • CC가 높을수록 테스트가 어렵고, 수정이 어렵다고 판단한다
    • 10 미만이 권장된다
    • 11-20 : 유지보수하기가 다소 어렵다고 판단
    • 21 ~ : Refactoring이 필요하다고 판단

 

 


Summary : Clean Method

 

Clean Method

  • Method를 호출하는 사람이 사용하기 용이해야 한다
  • Method를 유지보수하는 사람이 이해하고, 변경하기 용이해야 한다
  • Method를 유지보수하는 사람이 테스트하기 용이해야 한다

 

 

Clean Methods Principles

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

 

 

Clean Method를 위해서?

  • 적은 Parameter 개수
  • 명확한 Clean Name
  • 작은 크기
  • 명확한 역할
  • 중복 없는 상태
  • 높은 테스트 커버리지와 테스트 용이성

 

 

Clean Method는 하루 아침에 만들어지지 않는다

  • 충분히 좋은지에 대한 지속적인 읫미, 질문 그리고 개선이 필요하다
  • 좋은 Method의 기준에 대한 열린 토론과 그로 만들어지는 컨센서스가 필요하다
  • 모든 동료들이 함께하는 코드 품질 개선 문화가 필요하다
728x90

댓글