'최소화'에 해당하는 글 2건

336x280(권장), 300x250(권장), 250x250, 200x200 크기의 광고 코드만 넣을 수 있습니다.
예전에 쓴 들여쓰기 최소화라는 글에 많은 분들이 다양한 의견을 주셨습니다. 주신 의견들을 유심히 읽다 보니 해당 글에 대해 깊히 생각하는 기회를 가질 수 있었고, 자연스레 아래와 같은 세 가지 논제를 머리속에 떠올렸습니다.

첫 번째, 들여쓰기 최소화가 정말 가치있는 것인가? 만약 가치 있다면 논리적인 근거를 제시할 수 있는가?
두 번째, 진입점과 종료점을 각 하나씩만 유지해야 하는 것은 의미 있는 일인가?
세 번째, 긍정 조건과 부정 조건 중 어떤 것이 더 이해하기 좋은가? 만약 상황에 따라 적절히 사용해야 한다면 긍정 조건과 부정 조건을 선택하기 위해 사용하는 기준을 도출할 수 있을까?

최근 읽고 있는 켄트벡의 Implementation Patterns에는 위 논제에 대한 답변을 얻는 데 도움이 될만한 내용이 많이 담겨있었습니다. 저는 그동안의 저의 생각과, 최근 해당 책에서 얻은 지식들을 이용하여 위 세 가지 논제 중 첫번째 논제에 대한 저의 생각을 얘기해보고자 합니다.(참고로 Implementation Patterns의 Guard Clause와는 조금 다른 시점의 글입니다. 이 글은 이전 글에서 얘기했던 들여쓰기 최소화 자체에 집중한 글임을 밝힙니다)

들여쓰기를 한다는 것은 현재 들여쓰기 되고 있는 단락 위에 진입 조건이 존재한다는 것을 의미합니다. 조건문, 반복문, 메서드 등이 이러한 진입 조건이 될 수 있습니다.

만약 어떤 사람이 조건문에 속해 있는 하위 단락을 읽는다면, 하위 단락이 어떤 경우에 실행되는지를 '전제'로 인식하고 있어야 합니다. 그런데 이러한 전제가 많아지고 단락이 깊어지면 문제가 생깁니다. 아래 예제 코드는 이러한 문제를 잘 드러내고 있습니다.
void compute() {
    Server server = getServer();
    if (server != null) {
        Client client = server.getClient();
        if (client != null) {
            Request current = client.getRequest();
            if (current != null) {
                 processRequest(current);
            }
        }
    }
}

void compute() {
    Server server = getServer();
   if (server == null)
        return;
    Client client = server.getClient();
   if (client == null)
       return;
    Request current = client.getRequest();
   if (current == null)
       return;
   processRequest(current);
}

Implementation Patterns P71에서 인용

첫 번째 코드를 보면 읽는 사람이 전제로 유지해야 할 조건이 많다는 것을 볼 수 있습니다. 'server가 null이 아니고, client도 null이 아니며, current도 null이 아니면' 이라는 전제 조건이 processRequest에 이르기 전까지 단계적으로 머리속에 유지 되어야 합니다. 켄트백은 이러한 형태의 전제 조건들에 대해 '집중해야 할 것에 집중하지 못하게 방해하는 것들'이라고 얘기합니다. 실제로 위와 같은 코드는 집중해야 할 것에 집중하기 어렵게 하며 만약 else까지 존재한다면 더욱더 어려운 상황이 만들어집니다. 결국 코드를 이해하기가 어려워지는 것입니다.

반면 두 번째 코드는 동일한 일을 하면서도 보다 이해하기 쉬운 코드입니다. 코드에 윗 부분에 조건에 안 맞으면 바로 종료하는 코드가 있음을 볼 수 있습니다. processRequest에 이르렀을 때 첫번째 코드와는 달리 머리속에 전제 조건으로 유지해야 할 것이 없어집니다. 왜냐하면 'server가 null이면 종료','client가 null이면 종료','current가 null이면 종료' 이렇게 세 가지 조건 단락이 독립적으로 분리되어 이미 실행되었기에 더 이상 앞에 코드에 대해서 신경쓰지 않아도 되기 때문입니다.

만약 사람의 두뇌가 스택(Stack) 형태의 기억을 잘 할 수 있다면 첫번째 코드도 큰 문제는 아닐 것입니다. 하지만 저의 경우 스택 형태로 무엇인가를 기억하는 것은 쉽지 않았습니다. 따라서 몇단계의 전제 조건을 가지는 코드를 보면 한 세번째 전제 조건을 보는 중, 첫번째로 보았던 전제 조건을 잊어버려 허둥되곤 했습니다. 사실 이 문제는 저만의 문제는 아닌 것 같습니다. ANT의 depends 기능을 지나치게 활용하여 만들어진 빌드 스크립트를 분석하는 일은 저뿐만 아니라 다른 사람들도 무척 어려워 하더군요.

저는 첫 번째 논제인 '들여쓰기 최소화가 정말 가치있는 것인가?'라는 부분에 대해 '들여쓰기 최소화는 충분한 가치를 가지고 있다'고 주장하고 싶습니다. 왜냐하면 많은 경우 들여쓰기 최소화를 통해 더 이해하기 쉬운 코드를 만들 수 있기 때문입니다.

2008/01/15 ~ 2008/01/17

WRITTEN BY
차민창
르세상스 엔지니어가 사회를 이끌어나가는 상상을 하며!

,
336x280(권장), 300x250(권장), 250x250, 200x200 크기의 광고 코드만 넣을 수 있습니다.
최근 펄을 이용하여 프로젝트를 진행했습니다. 펄로 코딩을 하다보면 자바에서는 경험하지 못했던 몇가지 신선한 경험을 하게 됩니다. 이번 사건도 그 중 하나였던 것 같습니다.

제가 만든 펄 스크립트의 안정성을 위해 사용자가 입력한 내용을 한번 더 확인시켜줘야겠다는 생각이 들었습니다. 그래서 아래와 같이 코드를 만들었습니다. 사용자로부터 입력을 받아 Y나 y를 입력했을 경우에만 주실행로직을 수행하는 코드입니다.
print($sampleString."' 이 정말 맞습니까? (Y/N) ");
my $confirmation = <STDIN>;
chomp($confirmation);
if ($confirmation eq "Y" || $confirmation eq "y") {
    # 약 40줄 정도 되는 주요 처리 코드
   ...
   ...
   ...
}
# 코드의 끝
그런데 실제 코딩을 하고 나니 실행코드가 조건문 안에 들여쓰기 되어 갇혔다는 것을 발견했습니다. 그것도 40줄이나 말입니다 안정성을 향상 시키기 위해 들어간 선택적인 코드 때문에 이런 일이 발생 한 것은 다소 불합리해 보였습니다. 왠지 손님이 주인을 밀어내는 느낌이라고나 할까요?

거기에다가 제가 본 펄 강의에는 열악한 환경의 터미날을 이용할 때를 대비하여 코드의 가로길이가 80자를 넘어가지 않게하라고 강조했습니다. 80자가 넘어가면 코드를 보기가 힘들어지고 따라서 수정하기가 어려워진다고 하더군요. 들어쓰기는 가로길이를 늘어나게 하기 때문에 이러한 이유로도 제거되야 하는 것이 마땅해 보였습니다.

그래서 코드를 아래와 같이 수정했습니다.
print($sampleString."' 이 정말 맞습니까? (Y/N) ");
my $confirmation = <STDIN>;
chomp($confirmation);
exit if ($confirmation ne "Y" && $confirmation ne "y");

# 약 40줄 정도 되는 주요 처리 코드
...
...
...
# 코드의 끝
"$confirmation이 Y이거나 y이어야 함"을 "$confirmation이 Y가 아니고 y도 아닐 때"라는 부정조건으로 바꾸고 만약 해당 조건이 만족했을 때는 즉시 스크립트를 종료하도록 처리 한 것입니다.

이렇게 코드를 작성하니 40줄의 처리 코드는 조건문에서 빠져나올 수가 있었습니다. 그런데 가만히 보다보니 또 문제가 보였습니다. 그것은 새롭게 바뀐 조건식이 직관적이지 않다는 것입니다. 바뀐 조건식 'Y가 아니고 y도 아니어야 한다'라는 것은 처음에 있었던 "Y거나 y어야 함'보다 이해하기 어렵게 느껴졌습니다.

그래서 아래와 같이 한번 더 코드를 수정했습니다.
print($sampleString."' 이 정말 맞습니까? (Y/N) ");
my $inputFromUser = <STDIN>;
chomp($inputFromUser);
my $confirmation = $inputFromUser eq "Y" || $inputFromUser eq "y";
exit if ($confirmation == 0); #펄은 true/false 대신 1/0 개념이 사용 됨.

# 약 40줄 정도 되는 주요 처리 코드
...
...
...
# 코드의 끝
결국 이렇게 수정함으로 인해 직관적인 긍정조건을 사용 하면서도 40줄을 들여쓰기로부터 해방시킬 수 있었습니다. 소소하지만 재밌는 경험이였다고 생각합니다.

WRITTEN BY
차민창
르세상스 엔지니어가 사회를 이끌어나가는 상상을 하며!

,