Skip to content

Latest commit

 

History

History
235 lines (184 loc) · 6.85 KB

2장_의미있는이름_이주현.md

File metadata and controls

235 lines (184 loc) · 6.85 KB

2장 의미 있는 이름

  • 소프트웨어에서 이름은 변수, 함수, 클래스, 패키지 등 모든 곳에서 쓰인다.
  • 이름을 잘 지으면 여러모로 편한데, 이 장에서는 이름을 잘 짓는 간단한 규칙을 몇 가지 소개한다.

캡쳐1

https://xetown.com/topics/17032


의도를 분명히 밝혀라

  • 의도가 분명한 이름이 정말로 중요하다는 사실을 거듭 강조한다.
  • 좋은 이름을 지으려면 시간이 걸리지만 좋은 이름으로 절약하는 시간이 훨씬 더 많다.

잘못된 예시

    public List<int[]> test() {
        List<int[]> theList = new ArrayList<>();
        List<int[]> list = new ArrayList<>();

        for (int[] x : theList) {
            if (x[0] == 4) {
                list.add(x);
            }
        }
        return list;
    }

위 코드의 문제점은 다음과 같다.

  • theList, list는 어떤 변수인지?
  • theList에서 0번째 값이 왜 중요한지?
  • 값 4는 무슨 의미인지?

위 코드에 대해 지뢰찾기 게임을 만든다고 가정하면 다음과 같이 개선할 수 있다.

    private static final int STATUS_VALUE = 0;
    private static final int FLAGGED = 4; 
    
    public void test2() {
        List<int[]> gameBoard = new ArrayList<>();
        List<int[]> flaggedCells = new ArrayList<>();

        for (int[] cell : gameBoard) {
            if (isFlagged(cell[STATUS_VALUE])) {
                flaggedCells.add(cell);
            }
        }
    }
    
    private boolean isFlagged(int cellValue) {
        return cellValue == FLAGGED;
    }

그릇된 정보를 피하라

  • 여러 계정을 그룹으로 묶을 때 실제 List가 아니라면 accountList라 명명하지 않는다.
  • 계정을 담는 컨테이너가 실제 List가 아니라면 프로그래머에게 그릇된 정보를 제공하는 셈이다.
  • 이때는 accountGroup, bunchOfAccounts, Accounts라 명명한다.
// x
Account[] accountList = new Account[10];

// o
Account[] accounts = new Account[10];

의미있게 구분하라

// System.arraycopy(), Arrays.copyOf()

public static void copyChars(char[] a1, char[] a2) {
    for (int i = 0; i < a1.length; k++) {
        a2[i] = a1[i];
    }
}
  • 위 함수의 매개변수를 a1, a2가 아닌 source, destination을 사용한다면 코드 읽기가 훨씬 더 쉬워진다.
public static void copyChars(char[] source, char[] destination) {
    for (int i = 0; i < a1.length; k++) {
        a2[i] = a1[i];
    }
}

System.arraycopy() image

Arrays.copyOf() image


검색하기 쉬운 이름을 사용하라

for (int i = 0; i < 34; i++) {
    s += (t[i] * 4) / 5;
}


private static final int WORK_DAYS_PER_WEEK = 5;

int realDaysPerIdealDay = 4;
int sum = 0;
for (int i = 0; i < NUMBER_OF_TASK; i++) {
    int realTaskDays = taskEstimate[i] * realDaysPerIdealDay;
    int realTaskWeeks = realTaskDays / WORK_DAYS_PER_WEEK;
    sum += realTaskWeeks;
}
  • 위 코드에서 sum이 별로 유용하진 않으나 최소한 검색이 가능하다.
  • 이름을 의미있게 지으면 함수가 길어지지만, 검색이 보다 쉽다.

클래스 이름

  • 클래스 이름은 명사나 명사구가 적합하다.
    • Customer, WikiPage, Account, AddressParser

메서드 이름

  • 메서드 이름은 동사나 동사구가 적합하다.
    • postPayment, deletePage, save
    • getName, setName
  • 생성자를 중복정의 할 때는 정적 팩토리 메서드 를 사용한다.
Comple fulcrumPoint = Complex.fromRealNumber(23.0);

// 위 코드가 아래 코드보다 좋다

Complex fulcrumPoint = new Complex(23.0);

의미있는 맥락을 추가하라

// 맥락이 불분명한 변수
private void printGuessStatistics(char candidate, int count) {
    String number;
    String verb;
    String pluralModifier;

    if (count == 0) {
        number = "0";
        verb = "are";
        pluralModifier = "s";
    } else if (count == 1) {
        number = "1";
        verb = "is";
        pluralModifier = "";
    } else {
        number = Integer.toString(count);
        verb = "are";
        pluralModifier = "s";
    }

    String guessMessage = String.format(
            "There %s %s %s%s", verb, number, candidate, pluralModifier
    );
}
  • 위 함수는 코드를 끝까지 읽어보고 나서야 number, verb, pluralModifier 변수가 '통계 추측' 메시지에 사용된다는 걸 알 수 있다.
  • 불행히도 독자가 맥락을 유추해야만 한다.

// 맥락이 분명한 변수
public class GuessStatisticMessage {
    private String number;
    private String verb;
    private String pluralModifier;

    public String make(char candidate, int count) {
        createPluralDependentMessageParts(count);
        return String.format(
                "There %s %s %s%s", verb, number, candidate, pluralModifier
        );
    }

    private void createPluralDependentMessageParts(int count) {
        if (count == 0) {
            noLetter();
        } else if (count == 1) {
            oneLetter();
        } else {
            manyLetters(count);
        }
    }

    private void noLetter() {
        number = "0";
        verb = "are";
        pluralModifier = "s";
    }

    private void oneLetter() {
        number = "1";
        verb = "is";
        pluralModifier = "";
    }

    private void manyLetters(int count) {
        number = Integer.toString(count);
        verb = "are";
        pluralModifier = "s";
    }
}
  • GuessStatisticMessage라는 클래스를 만든 후 세 개의 변수를 넣었다.
  • 이로 인해 세 개의 변수는 통계(Statistic)와 관련된 변수임이 분명해진다.

정리

  • 문장이나 문단처럼 읽히는 코드 아니면 적어도 표나 자료구조처럼 읽히는 코드를 짜는 데만 집중해야 마땅하다.
  • 여느 코드 개선 노력과 마찬가지로 이름 역시 나름대로 바꿨다가는 누군가 질책할지도 모른다.
  • 그렇다고 코드를 개선하려는 노력을 중단해서는 안된다.
  • 이 장에서 소개한 규칙을 적용해 코드 가독성이 높아지는지 살펴보라.
  • 이름 개선을 통해 단기적인 효과는 물론 장기적인 이익도 보장한다.