else 구문을 제거해서 코드 가독성을 높이는 방법 free

2019-09-18


프릭 반 더 허르텐이 #bestpractices 태그를 달아서 올린 트윗입니다. 많은 경우 else 를 사용하지 않고 빠르게 리턴하면 가독성이 크게 좋아진다는 것입니다. 프릭이 첫직장에 출근한 첫날 사수가 펑션에는 하나의 리턴 구문만 있어야 한다고 이야기해주었는데, 인생 최악의 프로그래밍 조언이었다고 하네요.(관련 트윗) 저도 예전에 캐스트에서 else를 쓰지 말라는 영상을 본 이후로는 else를 되도록 자제하고 빠른 리턴을 쓰고 있는데 정말 실천하긴 쉽고, 효과는 좋은 코딩 습관이고 생각합니다. 캐스트 영상을 다시 보니 else를 쓰지 않는 방법을 세가지 제시했었네요. 간단히 정리해보았습니다.


1. 빠른 리턴을 사용하는 방어적 코딩


if() else()는 ‘만약 ~ 아니면 ~’의 구조서 왠지 if() 구문에 실행하고자 하는 코드를 작성해야할 것 같은 느낌을 줍니다. 하지만 거짓인 경우를 작성하고 바로 리턴을 해버리면 else를 쓸 필요가 없어집니다.


캐스트에서 보여준 예제를 봅시다.


`public function store() {
$input = Request::all();
$validation = Validator::make($input, ['username' => 'required']);

if(date('l') !== 'Fryday')
{
if($validation->passes())
{
Post::create($input);

return Redirect::home();
}
else
{
return Redirect::back()->withInput()->withError($validation);
}
}
else
{
throw new Exception('금요<span class="il">일</span>엔 <span class="il">일</span> 안해요!');
}
}
`

금요이 아니고 유효성 검사에 통과하면 Post를 생성한다에 초점이 맞춰져있습니다. 거꾸로 생각해보면 금요이면 더 이상 코드를 진행할 필요도 없고, 읽을 필요도 없습니다.


`public function store() {
$input = Request::all();
$validation = Validator::make($input, ['username' => 'required']);

if(date('l') === 'Fryday')
{
throw new Exception('금요<span class="il">일</span>엔 <span class="il">일</span> 안해요!');
}

if($validation->passes())
{
Post::create($input);

return Redirect::home();
}
else
{
return Redirect::back()->withInput()->withError($validation);
}
}
`

유효성 검사도 마찬가지죠. 유효성 검사를 통과하지 못하면 그 다음 코드는 의미가 없으니 다음과 같이 바꾸면 훨씬 읽기 좋습니다.


`public function store() {
$input = Request::all();
$validation = Validator::make($input, ['username' => 'required']);

if(date('l') === 'Fryday')
{
throw new Exception('금요<span class="il">일</span>엔 <span class="il">일</span> 안해요!');
}

if($validation->fails())
{
return Redirect::back()->withInput()->withError($validation);
}

Post::create($input);

return Redirect::home();
}
`

2. 유효성 검증을 미들웨어, 폼 리퀘스트로 이전


벨은 컨트롤러에 도달하기 전에 리퀘스트의 유효성을 검증하는 수단을 제공하고 있습니다. 대표적인게 미들웨어와 폼 리퀘스트인데요, 이 둘을 잘 활용하면 컨트롤러나 서비스, 모델 등에서 방어적 코딩 자체를 제거할 수 있습니다.


위의 예제의 경우 모든 리퀘스트에 금요 여부를 검사하는 코드를 넣는 대신 미들웨어로 빼내서 모든 리퀘스트에 적용할 수 있고, 유효성 검사는 폼 리퀘스트로 빼낼 수 있겠죠. 그럼 결과적으로 컨트롤러 매서드는 아래와 같이 가벼워집니다.


`public function store(PostStoreRequest $request) {
$input = Request::all();

Post::create($input);

return Redirect::home();
}
`

3. 다형성 활용


OOP의 SOLID 원칙 중 O에 해당하는 개방 폐쇄 원칙(Open Closed Principal) 이야기입니다. 전략패턴 이야기이기도 한데요. 상황에 따 처리 로직이 달지는 경우 if else를 계속 늘려나가는게 아니 다형성을 이용해서 if else 자체를 제거하는 방입니다. 물론 if else가 완전히 제거되는 건 아니지만.. 여튼 캐스트의 예제를 한 번 보시죠.


`function signUp($subscription)
{
if ($subscription == 'monthly')
{
$this->createMonthlySubscription();
}
elseif ($subscription == 'forever')
{
$this->createForeverSubscription();
}
}
`

$subsciption이 무엇인지에 따 다른 매서드를 출합니다. 이 경우 $subscription 종류가 늘어날 때마다 signUp() 매서드를 수정해야하는데, 인터페이스와 팩토리를 이용하면 $subscription 종류가 아무리 늘고 줄어도 signUp() 코드는 바꿀 필요가 없어집니다. else를 없앨 뿐만 아니 확장에는 열려있고, 변화에는 닫힌 전형적인 개방 폐쇄 원칙을 따르는 코드가 되는것이죠.


`function signUp(SubscriptionInterface $subscription)
{
$subscription->create();
}
`

마치며


2번, 3번은 활용려면 학습이 좀 필요하거나 코드를 많이 변경해야할 수 있지만, 1번은 바로 써먹을 수 있고 효과도 바로 체험할 수 있습니다. 아직 안써보신 분들 계시면 꼭 한 번 도입해보시기 바래요. 그럼 오늘도 즐거운 프로그래밍 하는 하루 되시길 바랍니다~!


1 1  55

2019년 9월 18


이현석

메쉬 코리아 개발자. 바쁜 팀장님 대신 알려주는 신입 PHP 개발자 안내서를 쓰고, 클린 아키텍처 인 PHP를 번역했습니다. 2020년에 출간될 Laravel Up & Running 2nd Edition을 번역하고 있습니다.