dev.jaieve 공부기록

[노개북] 클린코드 TIL(2022.02.22-23) 본문

IT의 이것저것/스터디

[노개북] 클린코드 TIL(2022.02.22-23)

제이브 2022. 2. 23. 23:47

DAY 5

🚀 오늘 읽은 범위 : 3장 함수


🔥 책에서 기억하고 싶은 내용

함수는 한 가지를 해야 한다. 그 한 가지를 잘 해야 한다. 그 한 가지만을 해야 한다.(p. 44)

의미 있는 이름으로 다른 함수를 추출할 수 있다면 그 함수는 여러 작업을 하는 셈이다.[G34]

함수 당 추상화 수준은 하나로!
함수가 확실히 ‘한 가지’ 작업만 하려면 함수 내 모든 문장의 추상화 수준이 동일해야 한다.(p. 45)

근본 개념과 세부사항을 뒤섞기 시작하면, 깨어진 창문처럼 사람들이 함수에 세부사항을 점점 더 추가한다.(p. 46)

서술적인 이름을 사용하라!
함수가 하는 일을 좀 더 잘 표현하므로 훨씬 좋은 이름이다. ... 함수가 작고 단순할수록 서술적인 이름을 고르기도 쉬워진다.(p.49)

객체를 생성해 인수를 줄이는 방법이 눈속임이라 여겨질지 모르지만 그렇지 않다. ... 변수를 묶어 넘기려면 이름을 붙여야 하므로 결국은 개념을 표현하게 된다.(p. 53)

함수 선언부를 찾아보는 행위는 코드를 보다가 주춤하는 행위와 동급이다. 인지적으로 거슬린다는 듯이므로 피해야 한다.(p. 56)

오류 코드 대신 예외를 사용하면 오류 처리 코드가 원래 코드에서 분리되므로 코드가 깔끔해진다.(p. 58)

try {
	deletePAge(page);
	registry.deleteReference(page.name);
	configKeys.deleteKey(page.name.makeKey());
} catch (Exception e) {
	logger.log(e.getMessage());
}

try/catch 블록은 원래 추하다. ... 그러므로 try/catch블록을 별도 함수로 뽑아내는 편이 좋다.(p. 58)

public void delete(Page page) {
    try {
        deletePageAndAllReferences(page);
    } catch (Exception e) {
        logError(e);
    }
}
private void deletePageAndAllReferences(Page page) throws Execption {
    deletePage(page);
    registry.deletePageAndAllReferences(page.name);
    configKeys.deleteKey(page.name.makeKey());
}
private void logError(Exception e) {
    logger.log(e.getMessage());
}

 


 

🤔 오늘 읽은 소감은? 떠오르는 생각을 가볍게 적어보자!

 

함수 인수 테스트 관점에서 보면 인수는 더 어렵다. 갖가지 인수 조합으로 함수를 검증하는 테스트 케이스를 작성한다고 상상해보라! 인수가 없다면 간단하다. ... 인수가 3개를 넘어가면 인수마다 유효한 값으로 모든 조합을 구성해 테스트하기가 상당히 부담스러워진다.(p. 50)

테스트코드를 작성할 줄 알아야하는 것이 개발자의 기본 스킬이라고는 하지만 아직 테스트코드 작성하는 방법에 대해 제대로 공부하지 못하여서 찔리는 마음으로 읽어나갔다. 스프링부트 스터디하면서 테스트코드 작성만큼은 제대로 익혀야겠다.

 

 

이항 함수 어떤 코드든 절대로 무시하면 안되니까. 무시한 코드에 오류가 숨어드니까.(p 52)

어제 회사에서 내가 수정했다가 까먹고 commit에 넣지 않는 소스코드가 있었다. deploy 브랜치에 push해서 jenkins에서 빌드가 되어야 하는데 되지 않는 오류가 당연히 발생했고, 그 원인을 찾아주신 팀장님 앞에서 민망해지는 경험을 했다. 어떤 코드든 무시하지 말자.

 

 

책을 읽으면서 잊고있었던 String.format() 함수를 마주했는데, 다항인수를 받는다고 해서 그 안을 한 번 들여다보고 싶어서 코드를 가져와봤다.

public static String format(String format, Object... args) {
    return new Formatter().format(format, args).toString();
}
public Formatter format(String format, Object ... args) {
    return format(l, format, args);
}

public Formatter format(Locale l, String format, Object ... args) {
        ensureOpen();

        // index of last argument referenced
        int last = -1;
        // last ordinary index
        int lasto = -1;

        List<FormatString> fsa = parse(format);
        for (FormatString fs : fsa) {
            int index = fs.index();
            try {
                switch (index) {
                case -2:  // fixed string, "%n", or "%%"
                    fs.print(null, l);
                    break;
                case -1:  // relative index
                    if (last < 0 || (args != null && last > args.length - 1))
                        throw new MissingFormatArgumentException(fs.toString());
                    fs.print((args == null ? null : args[last]), l);
                    break;
                case 0:  // ordinary index
                    lasto++;
                    last = lasto;
                    if (args != null && lasto > args.length - 1)
                        throw new MissingFormatArgumentException(fs.toString());
                    fs.print((args == null ? null : args[lasto]), l);
                    break;
                default:  // explicit index
                    last = index - 1;
                    if (args != null && last > args.length - 1)
                        throw new MissingFormatArgumentException(fs.toString());
                    fs.print((args == null ? null : args[last]), l);
                    break;
                }
            } catch (IOException x) {
                lastException = x;
            }
        }
        return this;
    }

 

함수에서 상태를 변경해야 한다면 함수가 속한 객체 상태를 변경하는 방식을 택한다.(p. 56)

1회독할 때는 이 말을 이해하지 못하고 넘어갔었는데, 지금은 이 문장을 두 번 정도 되내이면 이해가 된다. 6개월간 회사다니면서 공부를 헛투루 하지는 않았나보다.

 

 


 

🔎 궁금한 내용이 있거나, 잘 이해되지 않는 내용이 있다면?

if문 / else문 / while문 등에 들어가는 블록은 한 줄이어야 한다는 의미다. 대게 거기서 함수를 호출한다.(p. 44)

처음에는 이게 가능한가? 라는 생각이 들었다. 내가 회사에서 작성하는 if문들은 한줄로 끝나본 적이 없기 때문ㅇ... 크흠. 회사에서 소스코드 쓸 때 이 개념에 대해 인지하고 함수를 만들어보는 것도 좋을 것 같다.

플래그 인수
render(true)라는 코드는 헷갈리기 십상이다. ... 원래는 renderForSuite()와 renderForSingleTeset()라는 함수로 나눠야 마땅하다.(p. 52)

플래그 인수라는 표현을 처음 들어본 것 같아서 시간되면 찾아볼 생각이다.

반응형