1주차 발자국

1주차 발자국

이번 학습에서는 코드 품질을 높이기 위한 클린 코드 원칙과 리팩토링 기법을 집중적으로 다루었다. 단순히 코드 스타일을 개선하는 것이 아니라, 유지보수성과 가독성을 높이는 것이 궁극적인 목표라는 점을 다시금 깨달았다. 좋은 코드란 결국 팀원들과의 협업이 원활하고, 변경이 용이한 코드라는 점을 실감했다.

 

클린 코드와 추상화

우리가 클린 코드를 추구하는 이유

클린 코드의 핵심은 가독성을 확보하여 유지보수를 쉽게 만드는 데 있다. 이를 위해서는 동일한 레벨의 추상화가 필수적이다.

가독성은 왜 필요할까? 구현만 해서 사용자로 하여금 기능만 정상적이면 되지 않을까?

유지보수 업무를 하면서 느끼게 되었다. 가독성이 좋지 않은 코드는 코드를 이해하는데 오랜 시간이 걸리게 된다.

과연, 여기저기 기준없이 작성된 코드를 짠 개발자가 1년뒤에 다시 그 코드를 봤을때, 코드를 이해하는 시간이 짧을까?

당연하게도 처음보는 개발자보다는 조금은 빠를 수 있겠지만, 당사자도 오랜 시간이 걸릴꺼라 생각한다.

이처럼, 코드는 구현이 끝이 아니다. 우리는 구현된 코드를 다시 만질 일이 언젠가 생긴다.

 

프로그램의 정의

"프로그램 = 데이터 + 코드"

결국, 데이터를 어떻게 정의하고 조작할 것인가가 코드의 본질인가 보다.

 

추상과 구체

추상화는 구체적인 경험에서 출발해야 한다. 처음부터 완벽한 추상화를 기대하기보다, 먼저 실체적인 작업을 통해 패턴을 발견하고 점진적인 추상화를 진행하는 것이 효과적이다.

 

추상: 기계를 정비했다.

구체: 기계가 정상적으로 작동하지 않는 것을 발견한 후, 먼저 외관을 육안으로 점검하여 육안으로 보이는 손상여부를 확인하였다. 이후, 전원을 차단하고, 조립된 기계의 볼트와 너트를 분해하면서 기계의 주요 부품들의 마모 상태를 체크하고, 부품의 내부 손상정도를 파악했다. 문제의 원인은 주요 부품의 마모로 인한 진동 발생임을 확인하고, 기존의 부품을 탈거한 뒤, 새 부품을 장착하였다. 이후 다시 조립을 하고, 전원을 연결한 뒤 정상적으로 문제가 해결되었는지 테스트를 거친후 정비를 완료하였다.

 

 

이름 짓기

적절한 네이밍을 위해 다음과 같은 원칙을 적용하려 노력해본다.

  1. 단수/복수를 명확히 구분한다

  2. 의미를 모호하게 만드는 약어를 사용하지 않는다

  3. 특정 조직이나 개인만 이해할 수 있는 은어, 방언을 사용하지 않는다.

  4. 좋은 코드에서 네이밍 스타일을 습득한다.

 

메서드와 추상화

글에서 읽기 편안한 글이 되기 위해서는 한 문단이 하나의 주제를 가지면 된다. 마찬가지로 코드에서 메서드도 하나의 주제(책임)만을 가지게 되면 가독성이 좋아진다.

 

추상화 레벨

같은 레벨의 추상화가 유지되지 않으면, 코드의 흐름에 의문이 생기기 마련이다. 따라서 메서드를 추출할 때는 추상화 레벨을 맞추는 것이 중요하다.

 

매직 넘버와 매직 스트링

언어마다 상수를 지정하는 방식이 다르다. 매직 넘버와 매직 스트링을 제거하고 의미 있는 상수로 대체하는 것만으로도 코드의 가독성이 크게 향상된다.

 

SOLID

SOLID 원칙을 통해 코드 작성에 대한 깊은 고민을 할 수 있었다.

public class MissionDay4 {

    public boolean validateOrder(Order order) {
        if (hasNoItems(order)) {
            return false;
        }
        if (hasInvalidTotalPrice(order)) {
            return false;
        }
        if (isMissingCustomerInfo(order)) {
            return false;
        }
        return true;
    }

    private boolean hasNoItems(Order order) {
        if (order.getItems().isEmpty()) {
            log.info("주문 항목이 없습니다.");
            return true;
        }
        return false;
    }

    private boolean hasInvalidTotalPrice(Order order) {
        if (order.getTotalPrice() <= 0) {
            log.info("올바르지 않은 총 가격입니다.");
            return true;
        }
        return false;
    }

    private boolean isMissingCustomerInfo(Order order) {
        if (!order.hasCustomerInfo()) {
            log.info("사용자 정보가 없습니다.");
            return true;
        }
        return false;
    }
}

주어진 리팩토링 코드를 위와 같이 메서드를 분리하고, 최대한 부정조건을 사용하지 않으려 노력하면서 코드의 가독성이 높아지고 유지보수가 쉬워진다는 점을 경험할 수 있었다.

 

마치며

SOLID 원칙을 코드에 적용해보면서 설계기법의 생각을 해볼 수 있었다.

다음은 조금더 객체를 이용하고 객체의 목적과 책임에 맞게 구현하고, Getter, Setter를 무작정 사용하지 않는 연습을 깊이 해보는 것이 목표다.

채널톡 아이콘