Book/Clean Code

Clean Code - 깨끗한 코드와 의미 있는 이름

블로그 주인장 2024. 3. 21.

Chapter 01. 깨끗한 코드

좋은 코드와 나쁜 코드

 

나쁜 코드

  1. 성능이 나쁜 코드
    • 불필요한 연산이 들어가서 개선의 여지가 있는 코드
  2. 의미가 모호한 코드
    • 이해하기 어려운 코드
    • 네이밍과 그 내용이 다른 코드
  3. 중복된 코드
    • 비슷한 내용인데, 중복된 코드 -> 해당 코드는 버그를 발생시킬 수 있다.

 

나쁜 코드가 좋지 않은 이유

 

나쁜 코드가 좋지 않은 이유로는 3가지의 예시가 있습니다.

 

첫 번째는 깨진 유리창 법칙입니다.

즉, 나쁜 코드는 깨진 유리창처럼 계속 나쁜 코드를 만들어지도록 합니다.

 

생산성 저하

두 번째는 생산성 저하입니다.

나쁜 코드는 팀 생산성을 저하시킵니다. 기술부채를 만들어서 수정을 더 어렵게 합니다.

 

 

 

시스템 유지 보수

세 번째는 새로운 시스템을 만들어야한다 입니다.

현시스템을 유지보수하며 대체할 새로운 시스템 개발은 현실적으로 매우 어렵기 때문입니다.

 

 

나쁜 코드를 짜는 이유

 

그럼 나쁜 코드를 짜는 이유는 무엇이 있을 지 알아보겠습니다.

 

첫 번째로는 일정이 촉박하다는 것입니다.

코드를 구현할 때 주어진 일정 안에서 새로운 기능을 완성해야합니다.

하지만, 나쁜 코드는 생산성을 저하하기 때문에 일정을 맞추지 못하게 됩니다.

 

두 번째로는 영향 범위가 넓다는 것입니다.

코드를 짤 때 해당 코드의 영향범위가 넓어서 다른 부분에 대한 버그가 발생할 수 있다는 것입니다.

이로 인해 발생한 기술 부채는 부메랑처럼 되돌아와서 나쁜 코드를 짜게 된다는 것입니다.

 

 

클린 코드

비야네 스트롭스트룹(C++ 창시자)

 

 

그래디 부치(객체지향 대가)

 

 

클린 코드를 3가지로 부를 수 있습니다.

 

첫 번째로는 성능이 좋은 코드 입니다.

코드는 어떤 기능을 수행해야하기 때문에 그 기능을 수행할 수 있는 성능이 중요합니다.

 

두 번째로는 의미가 명확한 코드, 즉 가독성이 좋은 코드 입니다.

실제로 코드는 혼자서만 구현하는 것이 아닌, 팀 단위로 협업의 결과물이기 때문에 의미를 명확히 하고,

다른 사람이 읽기 좋도록 만드는 것이 중요합니다.

 

세 번 째로는 중복이 제거된 코드입니다.

재활용할 수 있도록 설계하는 것이 중요한데, 비슷한 코드가 중구난방으로 있는 것이 아니라,

중복이 제거되어 명료하게 만드는 것이 중요합니다.

 

 

Chapter 02. 의미 있는 이름

 

의미가 분명한 이름 짓기

int a;
String b;

System.out.printf("User Requested %s. count = %d", b, a);

 

위의 예시처럼 변수 a,b 처럼 의미가 불분명한 이름이 아닌 변수명을 분명하게 해서

아래의 코드처럼 구체적인 내용을 명시해야합니다.

 

class SalesItem {
    ItemCode code; 
    String name; 
    int count;
}

SalesItem selectedItem = salesItemRepository.getItemByCode(purchaseRequest.getItemCode())

System.out.printf("User Requested %s. count = %d", selectedItem.getName(), selectedItem.getCount());

 

루프 속 i j k 사용하지 않기

배열을 순회할 때 index를 의미하는 i를 사용하지 않고

advanced for문으로 대체하여 사용할 수 있습니다.

 

또한 위의 이미지처럼

람다식을 이용해서 사용할 수도 있습니다.

 

 

또한 위의 이미처럼 i, j, k 대신 맥락에 맞는 이름을 사용할 수도 있습니다.

 

i, j 대신 row, col / width, height 를 대신해서 사용할 수 있습니다.

또한 i,j,k 를 row, col, depth 라는 이름을 대체하여 맥락을 맞출 수 있습니다.

 

 

 

통일성 있는 단어 사용하기

똑같은 의미에 대해서는 똑같은 단어를 사용하는 것이 중요합니다.

 

예로 들어 Member / Customer / User 를 들 수 있습니다.

A 라는 개발자는 Member를 사용하고 B라는 개발자는 Customer를 사용한다고 하면,

똑같은 의미의 단어를 사용하면 혼란을 줄 수 있기 때문에 하나의 의미를 갖는 단어를 정해서 사용하는 것이 중요합니다.

 

변수명에 타입 넣지 않기

String nameString(👎) -> name
Int itemPriceAmount(👎) -> itemPrice
Account[] accountArray (👎)-> accounts

List<Account> accountList (👍)-> accounts, accountList 
Map<Account> accountMap(👍)

public interface IShapeFactory(👎) -> ShapeFactory
public class ShapeFactoryImpl(▲) -> CircleFactory

 

 

String nameString의 경우에는 해당 String 타입이 있기 때문에 굳이 사용할 필요가 없습니다.

 

itemPriceAmount 의 경우에는 Price와 Amount의 뜻이 중복되기 때문에 Amount를 사용할 필요가 없습니다.

 

List와 Map 같은 컬렉션 타입의 경우에는 변수명 뒤에 타입을 적어서

네이밍만 보더라도 타입명을 확인할 수 있도록 하는 것이 좋습니다.

 

Interface 와 구현체의 경우에는 팀에서 인터페이스와 클래스(구현체)의 네이밍을

팀이 정한 방향에 맞춰서 이해할 수 있는 코드를 구현하는 것이 좋습니다.

 

 

ETC. Google Java Naming Guide

현업에서 사용하는 Google Java Naming Guide 에 대해 알아보겠습니다.

 

Package Naming Guide

com.example.deepspace(👍)
com.example.deepSpace(👎)
com.example.deep_space(👎)

 

All lower case, no underscores

위의 문구를 직역하면, 모든 문자는 소문자로 사용하며, 언더바(_)를 사용하지 않는 것이 좋다고 합니다.

 

 

Class Naming Guide

//클래스는 명사, 명사구
Character, ImmtableList

//인터페이스는 명사, 명사구, (형용사)
List, Readable

//테스트 클래스는 Test로 끝내기
HashTest, HastIntegrationTest

 

UpperCamelCase(대문자로 시작)

위의 코드 예시처럼 클래스와 인터페이스는 대문자로 시작해야하고, 테스트의 경우에는 Test라는 단어로 끝맞쳐야합니다.

 

//메서드는 동사, 동사구
sendMessage, stop

// junit 테스트에 underscore 사용되기도 합니다.
// <methodUnderTest>_<state> 패턴
pop_emptyStack

 

LowerCamelCase(소문자로 시작)

위의 코드 처럼 메서드는 동사와 동사구로 되어 있기 때문에 소문자로 시작해야합니다.

또한, junit의 경우에는 <대상이 되는 메서드>_<상태> 패턴이 자주 사용됩니다.

 

 

 

본 포스트는 작성자가 공부한 내용을 바탕으로 작성한 글입니다.
잘못된 내용이 있을 시 언제든 댓글로 피드백 부탁드리겠습니다.
항상 정확한 내용을 포스팅하도록 노력하겠습니다.

반응형

'Book > Clean Code' 카테고리의 다른 글

Clean Code - 함수를 안전하고 간결하게 작성하기  (0) 2024.03.25

댓글