반응형

가독성 높이는 습관 - 심플하게 구성하기

 

 

코드를 작성한다는 것?

  • 조회, 검증, 저장, 변환 등을 통해 비지니스 로직을 표현하는 것
  • 단순하고 심플하게 작성해야 가독성이 높아짐
  • 가독성이 높아지면 유지보수가 용이해져 프로젝트 전체 비용이 감소함

 

 

본질에 집중하기 (화려한 것에 속지 않기)

- 내가 풀어야 하는 문제인가 무엇인가?

  • 새로운 기술, 새로운 개발방법론, 디자인패턴, 추상화, ....
class HelloWorld {
    public static void main(String[] args) {
        System.out.println("Hello World!");
    }
}

 

 

부정문보다 긍정문 사용하기

  • 긍정문을 통해 논리 단순화 시키기 (feat 캡슐화)
if (user.getAddress() != null && user.getStatus() == User.Status.AUTHENTICATION) {
     // doSomething
}

if (!user.unregistedAddress() && !user.unauthenticated()) {
     // doSomething (negative)
}

if (user.registedAddress() && user.authenticated()) {
     // doSomething (positive)
}

 

 

논리의 깊이를 줄이기

  • Early return 을 통해 단순화 하기
if ( ...
    // doSomething
else
    if ( ...
        // doSomething
    else
        if ( ...
            // doSomething
        else

 

/* Non-early return */
function getPayAmount() {
    let result;
    if (isDead)
        result = deadAmount();
    else {
        if (isSeparated)
            result = separatedAmount();
        else {
            if (isRetired)
                result = retireAmount();
            else
                result = normalPayAmount();
        }
    }
    return result;
}
/* Early return */
function getPayAmount() {
    if (isDead) return deadAmount();
    if (isSeparated) return separatedAmount();
    if (isRetired) return retiredAmount();
    return normalPayAmount();
}

 

/* Non-early return */
public SomeType aMethod() {
    SomeType result = null;
    
    if (guardCondition()) {
        doStuffToResult(result);
        doMoreStuffToResult(result);
    }
    
    return result;
}
/* Early return */
public SomeType aMethod() {
    SomeType result = null;
    
    if (!guardCondition()) {
        return result;
    }
    
    doStuffToResult(result);
    doMoreStuffToResult(result);
    
    return result;
}

 

  • 분기문의 내용이 길다면, 심플한 것 우선 처리하기
public void foo(User user) {
    if (user.registed()) {
        // 한눈에 들어오지 않는 복잡한 로직
        // (한 화면에 들어오지 않는다고 가정)
        // 뭔가 복잡한 작업을 진행함
        // 뭔가 복잡한 작업을 진행함
        // 뭔가 복잡한 작업을 진행함
        // 뭔가 복잡한 작업을 진행함
        // 뭔가 복잡한 작업을 진행함
        // 뭔가 복잡한 작업을 진행함
        // 뭔가 복잡한 작업을 진행함
        // 뭔가 복잡한 작업을 진행함
        // 뭔가 복잡한 작업을 진행함
    } else if (user.unauthenticated()user.registed()) {
        // 무엇인지 모르겠으나 로직이 한줄에 끝남
    } //뭔가 분기가 더 있다고 가정
    
    // 뭔가 공통적인 작업을 진행함
}
public void foo(User user) {
    if (user.unauthenticated()) {
        // 무엇인지 모르겠으나 로직이 한줄에 끝남
    } else if (user.registed()) {
        // 한눈에 들어오지 않는 복잡한 로직
        // (한 화면에 들어오지 않는다고 가정)
        // 뭔가 복잡한 작업을 진행함
        // 뭔가 복잡한 작업을 진행함
        // 뭔가 복잡한 작업을 진행함
        // 뭔가 복잡한 작업을 진행함
        // 뭔가 복잡한 작업을 진행함
        // 뭔가 복잡한 작업을 진행함
        // 뭔가 복잡한 작업을 진행함
        // 뭔가 복잡한 작업을 진행함
        // 뭔가 복잡한 작업을 진행함
    } //뭔가 분기가 더 있다고 가정
    
    // 뭔가 공통적인 작업을 진행함
}

 

 

  • 상세 구현은 숨기고 비지니스 로직만 표현하기
public void order(User user, long bookId) {
    Book book = bookRepository.findByBookId(bookId)
            .orElseThrow(() -> new RuntimeException("도서가 존재하지 않습니다."));
            
    BookStock bookStock = bookStockRepository.findByBookId(bookId)
            .orElseThrow(() -> new RuntimeException("재고 정보가 존재하지 않습니다."));
            
    UserInfo userInfo = userInfoAdaptor.findUserInfo(user)
            .orElseThrow(() -> new RuntimeException("재고 정보가 존재하지 않습니다."));
            
    if (!book.onSale(LocalDateTime.now()))
        throw new RuntimeException("판매 중이지 않은 도서입니다.");
        
    if (!userInfo.isDormant())
        throw new RuntimeException("휴면 고객은 구매할 수 없습니다.");
    
    if (!book.enoughAge(userInfo.getAge()))
        throw new RuntimeException("도서를 구매할 수 없는 나이입니다.");
        
    if (!bookStock.enoughStock())
        throw new RuntimeException("도서 재고가 부족합니다.");
        
    // 기타 조건체크
    BookOrder bookOrder = BookOrder
            .builder()
            .bookId(book.getId())
            .userId(user.getId())
            .build();
    bookStock.decreaseStock();
    
    bookStockRepository.save(bookStock);
    bookOrderRepository.save(bookOrder);
}
public void order(User user, long bookId) {
    Book book = findBook(bookId);
    UserInfo userInfo = findUserInfo(user);
    BookStock bookStock = findBookStock(bookId);
    
    chackOnSale(book);
    checkDormant(userInfo);
    checkEnoughAge(book, userInfo);
    checkEnoughStock(bookStock);
    // 기타 조건체크
    
    bookStock.decreaseStock();
    bookStockRepository.save(bookStock);
    bookOrderRepository.save(createBookOrder(user, book));
}
  • 코드의 추상화 레벨을 높여서 사람이 이해하기 쉬운 코드로 작성

 

 

정리

- 코드 작성 = 비지니스 로직의 표현

- 코드는 심플해야 가독성이 높아짐

- 코드를 심플하게 만드는 방법들

  • 1. 본질에 집중하기
  • 2. 부정문보다는 긍정문 사용
  • 3. 코드 깊이 줄이기 (Early return, 심플한 로직 우선 처릭)
  • 4. 상세 구현 숨기기

 


반응형

+ Recent posts