본문 바로가기
Java

클린 코드 작성 : 더 나은 개발자가 되기 위한 단계

by kellis 2020. 11. 15.

※ 이 글은 Sushil Ale가 쓴 Writing Clean Code: A Step Towards Being a Better Developer의 번역본입니다.

 

 

개발자들은 빠르게 변화하는 기술 시장에서 살아남기 위해 기술 스택을 알고, 숙련도를 높이는 등 개인의 스킬을 향상하기 위해 노력합니다. 보유기술을 늘리기 위해 새로돈 도구, 언어, 기술들을 배우려 합니다. 하지만 이렇듯 새로운 역량을 키우는 것 외에도 중요한 것은 어떻게 코드를 작성하는가에 대한 고찰입니다. 코드는 지속적으로 추가되거나 수정되고, 디버그 할 필요가 있기 때문에 깨끗하고 이해하기 쉬운 코드가 되어야 합니다. 쉽게 읽을 수 있고, 이해할 수 있고, 유지 보수할 수 있는 프로그램을 작성하기 위해 클린 코드의 지침을 따르는 것을 권고합니다. 

 

클린 코드를 작성한다는 것은 네이밍 컨벤션이나 주석, 에러 핸들링, 함수, 객체, 데이터 구조와 같이 프로그램의 다른 면을 고려하는 것을 의미합니다. 좋은 코드를 작성하기 위해 고려해야 하는 사항은 다음과 같습니다. 

 

 

(1) 의미있는 이름

좋은 이름은 많은 정보를 제공하고 프로그램에 명확성을 더해줍니다. 개발자가 코드의 의도를 나타내기 위해 의미 있는 이름을 붙일 때는 클래스, 변수, 함수가 거의 언급되지 않습니다. 다음과 같은 요점들이 의미 있는 이름을 만드는데 도움을 줍니다.

  • 의도가 드러나는 이름
    클래스, 멤버변수, 함수, 지역변수에 그들의 사용성을 나타내는 이름을 주는 것은 더 읽기 쉽게, 이해하기 쉽게, 유지 보수하기 쉽게 해 줍니다. 
  • 의미 있는 구별을 하고 불필요한 정보는 피하라.
    개발자는 동일한 범위 또는 변수의 타입 내에 유사한 객체를 써야 합니다. 그런 상황에서 좋은 이름을 선택하는 것은 명료하게 구분하는 데에 중요합니다. 예를 들어, obj1, obj2를 사용하는 것 대신에 그들의 사용성을 설명하는 이름을 사용해야 합니다. 
  • 발음할 수 있는 이름
    당신이 프로그램에 정의하는 클래스들의 이름을 기억할 수 있습니까? 작은 프로젝트라면 쉽겠지요. 그러나 프로그램은 점점 커집니다. 모든 클래스, 변수, 함수들을 기억하기에는 어렵죠. 발음할 수 있는 이름을 사용하는 것은 가독성과 이해력을 높이고 그것이 사용되는 범위 내에서 기억하기 쉽게 만들어줍니다. 
  • 찾을 수 있는 이름
    찾을 수 있는 이름을 사용하라는 것은 file1, file2, var1 등과 같이 일반적인 이름을 피하는 것을 의미합니다. 이 용어들은 어디서나 사용될 수 있고 사용 범위를 명시하지 않기 때문에 찾기 어렵습니다. 검색은 진보된 IDE를 이용하면 쉽지만 여전히 시간을 소비하고 상대적으로 큰 결과를 일으킵니다. 검색 가능한 이름을 사용하면 위치를 쉽게 찾을 수 있고 검색 시간을 줄일 수 있습니다.
  • 인코딩을 피하라.
    종종 우리는 변수의 타입이 무엇인지 명시하기 위해 intSum 또는 strName을 사용합니다. 그러나 변수 이름 앞에 유형 인코딩을 추가하면 정보가 추가되는 것이 아니라 가독성만 떨어집니다. (그냥 sum, name이 더 좋은 이름 입니다.)

 

(2) 주석

코드의 주석은 코드를 이해하는데 중요한 역할을 합니다. 우리는 종종 프로그램에 주석을 달고 각 문장에 대해서 주석을 달도록 교육받습니다. 그러나 문제는 주석이 "어디에서나 필요한지"입니다. 대답은 "아니오"입니다. 

  • 법률과 관련된 주석
    만약 저작권과 같은 법적 문제가 있는 경우에는 주석을 추가하세요.
  • 정보성 주석
    만약 다른 사람들에게 분명히 가치 있는 것이라고 생각되는 정보가 있다면 주석을 작성하세요 (예를 들어 구현된 알고리즘) 
  • 의도에 대한 설명
    우리는 의도하지 않았고, 그렇게 하면 안 되지만 실제 상황에서는 할 수밖에 없는 경우가 있습니다.  그런 경우에 의도를 설명하는 주석을 두는 것이 좋습니다. 
  • 결과에 대한 경고
    우리는 어떤 일을 하는 함수를 작성합니다.  그런데 의도하지 않은 시나리오에서 사용하는 경우 비이상적인 결과를 야기합니다. 그러한 경우에 결과를 설명하는 주석을 달아주는 것은 매우 유용합니다.

 

(3) 함수

우리는 어떤 일에 대해 책임을 지는, 어떤 특정한 문제를 해결하는 함수들을 작성합니다. 함수들에 대해서 "함수 코드가 얼마나 긴가(long)", "단일 기능을 사용하기에 적절한가"와 같은 질문은 모든 개발자들에게 매우 중요합니다. 하나의 함수가 너무 길거나 많은 일을 하는 것은 복잡도를 증가시키고, 유지 보수하기 어렵게 만듭니다. 따라서 함수는 다음과 같은 속성을 가져야 합니다.

  • 상대적으로 작게
    함수는 가능한 한 작게 만들어야 디버깅하기 쉽고, 이해하기 용이하며 수정하기 편합니다. 일부는 라인의 수로 함수를 정의하고 일부는 함수의 내용이 스크린에 완벽히 보일 수 있어야 한다고 생각합니다. 그것은 개발자가 원하는 정도에 따라 달려있습니다. 그러므로 함수는 다른 사람이 읽기 쉽고 디버깅하기 쉽고 수정하기 쉽도록 하기 위해 상대적으로 작아야 합니다. 
  • 하나의 일만 하도록, Side Effect는 없도록
    만약 함수를 유지 보수하기 편리하고 더 이해하기 쉽도록 만들고 싶다면, 단일 책임을 가지도록 해야 합니다. 단일 책임이라는 것은 오직 하나의 일만 수행하는 것을 의미합니다. 단일 책임은 사이드 이펙트를 감소시킵니다. 만약 하나의 함수가 의도된 목적뿐만 아니라 다른 것도 수행한다면 그것은 좋지 않습니다. 그런 함수들은 언제나 사이드 이펙트를 일으킬 수 있습니다. 
  • 한 단계의 추상화
    함수는 이름을 통해서 그것의 사용성을 드러내고 상세 내용은 감춥니다. 함수는 그것이 책임을 지는 상세 내용을 숨겨야 합니다. 이것이 한 단계의 추상화를 제공해야 한다는 것을 의미합니다.

 

(4) 에러 처리

에러에서 100% 자유로운 소프트웨어는 없습니다. 따라서 에러 처리는 애플리케이션을 개발하는데 있어 중요한 부분입니다. 우리는 에러들이 언제 어디서 일어나는지 알 수도 있고 모를 수도 있습니다. 따라서 어플리케이션을 개발하는 동안 에러에 대해서 준비를 해야하지요. 에러는 적절하게 처리되어야 합니다. 그렇지 않으면 프로그램이 죽을 수도 있지요. 더 나은 에러 처리를 위해, 어플리케이션을 안전하게 유지하기 위해 다음과 같은 가이드라인이 유용할 것입니다.

  • 에러 코드 대신 Exception(예외)를 선호해라.
    0,-1, ERR과 같은 에러 코드를 리턴하는 것 대신 기본 Exception 또는 사용자 Exception을 정의해서 사용하는 것이 더 좋습니다. Exception이 이름을 가지고 있기 때문에 에러가 왜 발생했는지에 대해 이해하기 더 유용합니다. 예를 들어, "file not found" 에러에 직면했을 때 코드 0 대신 FileNotFoundException을 보여주는 것이 더 이해하기 쉽고 에러의 유형을 확인하기도 쉽습니다.
  • Exception과 함께 맥락을 제공해라.
    Exception은 주의해서 처리해야 합니다. 이것은 유연성을 제공할 뿐만 아니라 복잡성도 증가시킵니다. 따라서 언제 Exception이 일어나던지 그것에 대한 문맥을 제공하는 것이 좋습니다. Exception은 디버깅을 위해 많은 정보를 제공하고 문맥을 제공하는 것은 그것을 더 의미 있게 만들어 줍니다. 예를 들어, 데이터베이스의 테이블에 쿼리를 날렸고 "record not found"라는 Exception을 던질 필요가 있습니다. 그런 경우에 Exception만 던지는 것은 아무런 의미가 없습니다. 만약 "record not found"라는 메시지를 함께 전달해 준다면 그것이 의미가 있게 되지요. 많은 경우에 같은 타입의 Exception을 사용할 수도 있기 때문에 메시지 같은 문맥을 전달해주는 것은 필수적입니다. 
  • Null 값을 리턴하거나 전달하지 마라.
    Null을 리턴하거나 전달하는 것은 많은 문제를 야기시킵니다. 이것이 언제 발생하는지도 불확실합니다. Null 값을 받아들이고 리턴하는 함수는 비정상적인 상태입니다. 불확실성을 예방하기 위해 함수를 부르기 전에 항상 파라미터들을 검증해야 하고 값이 있으면 값을 반환해야 합니다. 만약 값이 없으면 문맥에 맞는 Exception을 던질지언정 Null을 반환해서는 안됩니다.

 

위의 가이드라인을 통해서 여러분들이 더 나은 코드를 작성하는 데에 도움이 되었기를 바랍니다. 지속적인 과정을 통해서 평소에 이 지침들을 계속 생각할 필요가 있습니다. 만약 클린 코드에 대해서 더 알고 싶다면, Clean Code: A Handbook of Agile Softward Craftsmanship을 읽어보시기를 권유드립니다.

'Java' 카테고리의 다른 글

String Constants Pool  (0) 2020.11.15
Java(JVM) Memory Model(Runtime Data Areas)  (0) 2020.10.21
Static 사용을 피해야 하는 이유  (1) 2020.10.20
Lambda, 무엇이 단점일까?  (0) 2020.10.20
Lambda 무엇이 좋을까?  (0) 2020.10.20

댓글