inflearn logo
강의

강의

N
챌린지

챌린지

멘토링

멘토링

N
클립

클립

로드맵

로드맵

지식공유

[인프런 워밍업 클럽 3기] BE 클린코드&테스트 - 1주차 발자국

rjf1138
0

강의 수강 내용 핵심 정리

1. 클린 코드와 추상화


2. 이름 짓기(Naming)


3. 메서드 설계와 선언부


4. 가독성을 위한 코드 스타일


5. 객체지향 설계 원칙 (SOLID)

(1) 단일 책임 원칙 (SRP)

(2) 개방-폐쇄 원칙 (OCP)

(3) 리스코프 치환 원칙 (LSP)

(4) 인터페이스 분리 원칙 (ISP)

(5) 의존성 역전 원칙 (DIP)


6. 예외 처리와 NULL 다루기


7. 코드 리팩토링 접근법


8. 상속보다는 조합을 사용하자


9. Value Object(VO)와 Entity

equals() & hashCode()를 재정의해야 하는 이유와, hash 자료형을 구현하는 방법을 학습할 필요가 있음.


10. 일급 컬렉션(First-Class Collection)


11. Enum의 특성과 활용


12. 다형성(Polymorphism) 활용하기


13. 숨겨진 도메인 개념 도출하기


미션 해결 과정 정리

Day 2 미션

우리는 매일 숨을 쉬고 음식을 소화하지만, 이를 매번 세밀하게 설명한다면 너무 복잡하고 불편할 것입니다.

이 미션을 수행하면서, 최근 읽고 있는 《데이터 중심 애플리케이션 설계》(a.k.a DDIA)에서 본 문장이 떠올랐습니다.

"우발적 복잡도(accidental complexity)를 제거하기 위한 최상의 도구는 추상화다."

여기서도 추상화라는 개념이 강조됩니다. 또한, 책의 예시에서도 “기계어, CPU 레지스터, 시스템 호출을 추상화한 것이 고수준 프로그래밍 언어이다”라는 설명이 나옵니다. 이는 강의에서 들었던 내용과도 동일합니다.

컴퓨터가 실제로 실행하는 것은 어셈블리어와 같은 저수준 코드이지만, 개발자인 우리가 이를 직접 다루는 것은 어렵고 비효율적입니다. 따라서, 우리는 Java 같은 고수준 프로그래밍 언어를 사용하며 자연스럽게 추상화의 이점을 누리고 있는 것입니다.

또 다른 추상화의 예시로 떠오른 것은 Spring에서 Database(ex: MySQL)를 사용하기 위한 ORM인 JPA, Spring Data JPA입니다.

우리는 데이터베이스를 사용하기 위해 보통 다음과 같은 작업을 수행해야 합니다.

  1. Connection Pool에서 Connection을 가져옴

  2. 데이터베이스와 연결을 맺음

  3. SQL 쿼리를 작성하고 실행

  4. 결과를 받아서 처리

이 과정은 데이터베이스를 사용할 때마다 반복되며, 이는 우발적 복잡도를 증가시킵니다. 이를 해결하기 위해 JPA와 Spring Data JPA 같은 ORM이 등장했습니다.

즉, 선배 개발자들이 데이터베이스 작업의 복잡성을 추상화하여 보다 간결하고 일관된 방식으로 데이터를 다룰 수 있도록 한 것입니다.

또한, Java의 interface 역시 추상화의 대표적인 사례라고 생각합니다.

이렇듯, 이번 미션에서는 다시 한번 올바른 추상화의 중요성과 그것이 Readable Code 를 만드는데 얼마나 큰 요소를 차지하는지 잘 알 수 있었습니다.

애플리케이션 설계, 코드 구현 등 여러 곳에서 추상이라는 개념이 얼마나 중요하게 여기는지 다시 한번 알 수 있었고, 적재적소에 잘 써먹어야겠다는 생각을 많이 했습니다.


Day 4 미션

AS-IS

public boolean validateOrder(Order order) {
    if (order.getItems().size() == 0) {
        log.info("주문 항목이 없습니다.");
        return false;
    } else {
        if (order.getTotalPrice() > 0) {
            if (!order.hasCustomerInfo()) {
                log.info("사용자 정보가 없습니다.");
                return false;
            } else {
                return true;
            }
        } else if (!(order.getTotalPrice() > 0)) {
            log.info("올바르지 않은 총 가격입니다.");
            return false;
        }
    }
    return true;
}

Readable 하지 못한 점 파악

TO-BE

@Service
@RequiredArgsConstructor
public class OrderService {
	...
	public boolean validateOrder(Order order) {
    if (order.hasNoItems()) {
        throw new OrderException("주문 항목이 없습니다.");
    } 
    if (order.hasNotCustomerInfo()) {
		    throw new OrderException("사용자 정보가 없습니다.");
    }
    if (order.isInValidTotalPrice())) {
        throw new OrderException("올바르지 않은 총 가격입니다.");
    }
    return true;
	}
}
@Entity
@Table(name = "orders")
@Where(clause = "deleted_at IS NULL")
@SQLDelete(sql = "UPDATE orders SET deleted_at = NOW() WHERE id = ?")
public class Order {
	...
	private boolean hasNoItems() {  
    return this.items.isEmpty();  
	}
	
	private boolean hasNotCustomerInfo() {  
    return this.customInfo.isEmpty();  
	}  
  
	private boolean isTotalPriceLessThanZero() {  
		return this.items.stream().mapToInt(Item::getPrice).sum() <= 0;
	}  
}
public class OrderException extends RuntimeException {
	public OrderException(String message) { 
		super(message); 
	} 
}

SOLID에 대하여 자기만의 언어로 정리해 봅시다.

SRP(단일 책임 원칙)

OCP(개방-폐쇄 원칙)

LSP(리스코프 치환 원칙)

ISP(인터페이스 분리 원칙)

DIP(의존관계 역전 원칙)

개인적으로 Spring Bible 로 생각하는 토비의 스프링, 김영한님의 Spring 강의를 듣고 채득한 내용을 바탕으로 SOLID 개념을 정리해봤습니다.


일주일 회고

다른 워밍업 클럽과는 달리 한 달 안에 2개의 강의, 그것도 강의당 대략 13시간 정도의 강의를 수강해야 해서 강의를 빨리 들어야 하는 압박감이 들어서 개인적으로는 쉽지 않았던 것 같습니다.

그래도, 진도에 늦지 않게 강의를 수강한 것 같아서 무척 뿌듯하네요.

그리고, 이번주에는 미션이 2개 있었는데 해당 미션을 수행하면서 강사님이 중요하게 생각하는 건 무엇인지, 강의를 들을 때 어떤 걸 중점적으로 들어야 하는지에 대한 일종의 가이드라인을 주시는 것 같아서 강의를 수강하기에 좀 더 수월 했던 것 같습니다.

현재, 2년 2개월을 회사 생활을 마치고, 이직 준비를 한지 벌써 1년이 지나면서 바쁘게 취직 준비를 하고 있지만 그럼에도 박우빈님의 강의를 들으면서 클린코드/테스트코드를 공부하기 정말 잘했다는 소위 말하는 돈값을 한다는 강의를 느꼈습니다.

남은 3주도 열심히 하여 완강은 물론 우수러너도 되어보도록 하겠습니다.

답변 0