inflearn logo
강의

강의

N
챌린지

챌린지

멘토링

멘토링

N
클립

클립

로드맵

로드맵

지식공유

[인프런 워밍업 클럽 3기 - 백엔드 코드] 발자국 1주차

10
1

👣 발자국 책갈피

미션PR 책갈피

🤔 인프런 워밍업 클럽 스터디 신청 계기

나는 인프런 워밍업 클럽 스터디 신청하기 한 달 전에 스터디 과정에 쓰이는 로드맵 강의를 이미 완강하였다.

그럼에도 불구하고 강의를 수강하기 전부터 우빈님의 팬(?)이였기 때문에 이메일을 받자마자 신청을 할 수 밖에 없었다.

항해 플러스 8기 백엔드 과정을 앞두고 약 2주간 겹치는 구간이 있어 잠시나마 고민을 하긴 했지만?..

복습 차원에서 미션과 발자국을 통해 학습내용을 더 딥하게 파고들어 성장하고자 신청하게 되었다.

image

👣 발자국이란?

인프런 워밍업 클럽에서 이야기하는 발자국이란 다음과 같다.

주 1회, 일주일 동안 배운 내용을 바탕으로 남기는 학습 일기이자 회고이다.

매주 강의를 요약하고 기록하면서 강의 내용을 제대로 이해했는지 확인하고, 보완할 부분을 찾는다.

기록을 통해 배운 내용에 대해 메타인지 하는 시간을 가진다.

나는, 이번 과정에서는 강의를 재수강하지는 않고

섹션 별로 우빈님께서 제공해주신 키워드 정리를 통해 학습을 진행할 예정이다.

💡 자기만의 언어로 키워드 정리하기

섹션 2. 추상

[다른 추상화 레벨]

public class Order {

    public void process() {
        paymentService.pay(); // 고수준 추상화 📈
        System.out.println("결제 완료"); // 저수준 추상화 📉 
    }
}

 

[동등한 추상화 레벨]

public class Order {

    public void process() {
        paymentService.pay(); // 고수준 추상화 📈
        printCompletedPay(); // 메서드를 분리하여 고수준의 추상화를 동등하게 유지 ✅
    }

    private void printCompletedPay() {
        System.out.println("결제 완료");
    }
}    

image

섹션 3. 논리, 사고의 흐름

image

섹션 4. 객체 지향 패러다임

[낮은 응집도]

public class OrderService {
            
    public Order createOrder(Product product) {
        // 주문 생성 로직 
    }
            
    public void sendEmail(Order order) {
        // 이메일 전송 로직은 OrderService의 관심사가 아니다. ❌
    }
}

 

[높은 응집도로 해결]

객체를 분리함으로써 응집도가 올라간다.

public class OrderService {
            
   public Order createOrder(Product product) {
       // 주문 생성 로직 
   }
}
        
public class OrderEmailSender { // 객체를 분리하여 높은 응집도로 설계 ✅
        
   public void sendEmail(Order order) {
       // 이메일 전송 로직
   }
}

 

[높은 결합도]

public class OrderService {
            
    private EmailService emailService = new EmailService(); // 높은 결합도 ❌
}

 

[낮은 결합도로 해결]

인터페이스와 DI를 활용하여 결합도를 낮춘다.

public interface EmailSendable {

}

public class OrderEmailSender implements EmailSendable {

}

public class OrderService {
  
    private final EmailSendable emailSendable;
  
    public OrderService(EmailSendable emailSendable) {
        this.emailSendable = emailSendable; // 높은 결합도를 해결한다. ✅
    }
}

객체끼리의 협력과 책임을 통해 프로그램을 만들 수 있다.

가장 중요한 것은 관심사의 분리이고 높은 응집도와 낮은 결합도를 가진 설계를 가지는 것이 중요하다.

 

image

섹션 5. 객체 지향 적용하기

변하는 것과 변하지 않은 것을 구분해서 보는 훈련이 필요하다.

[이메일 전송 개념에서 미래를 예견하고 숨겨진 도메인 개념을 도출]

현재의 최선에서는 이메일만 발송하지만 미래에 카카오톡 알림톡이나 혹은 다른 알림에 대한 도메인 개념을 도출해보자

public interface Sendable { // 미래를 예견하고 도매인 개념을 도출 ✅
    
    void send(String message);
}

public interface EmailSendable extends Sendable { 
 
    @Override
    void send(String message);
}

image

👨🏻‍💻 미션 회고

 

[미션 Day 2]

미션 PR : https://inf.run/dmW3B

1⃣ 추상과 구체 예시

강의 내용에서도 계속 등장하듯이 추상구체는 이번 강의에서 가장 핵심이 되는 단어들이다.

이 미션을 접했을 때, 단순히 추상과 구체에 대한 예시를 들기보다 개발적인 관점에서 추상과 구체에 대해 접근하려고 노력했다. (적절한 예시인지는 잘 모르겠으나..😂)

해당 미션을 통해, 추상화가 단순히 쉽지 않다는 걸 느꼈으며 개발적인 관점에서도 더 읽기좋은 코드를 작성하기 위해선 추상화를 잘 해야겠다라는 생각이 들었다.

 

[미션 Day 4]

미션 PR : https://inf.run/1P5bV

1⃣validateOrder 메서드를 읽기 좋은 코드로 리팩토링 하기

미션 PR에도 코멘트를 달았지만 도메인 레이어의 로깅이 하는 구현 부가 포함된 게 신경이 쓰인다.

도메인 레이어에서 의존성을 주입받지는 않아 객체 분리가 맞는지 모호하다.

image

[기존 코드]

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;
}

[리팩토링 이후 코드]

public class Order {

    private static final Logger log = Logger.getLogger(Order.class.getName());

    private final Items items;
    private final Member member;
    private final int totalPrice;

    private Order(Items items, Member member, int totalPrice) {
        this.items = items;
        this.member = member;
        this.totalPrice = totalPrice;
    }

    public boolean validate() {
        if (items.isEmpty()) {
            log.info("주문 항목이 없습니다.");
            return false;
        }

        if (totalPrice <= 0) {
            log.info("올바르지 않은 총 가격입니다.");
            return false;
        }

        if (member.hasNotInfo()) {
            log.info("사용자 정보가 없습니다.");
            return false;
        }

        return true;
    }
}

 

2⃣ SOLID에 대하여 자기만의 언어로 정리

사실, 객체 지향에 대해 학습한 사람들 중 SOLID를 모르는 사람은 없을 것 이다.

그치만 여기서의 포인트는 자기만의 언어이다.

image

위에서도 강의에 대한 정리내용을 작성할 때 "💡 자기만의 언어로 키워드 정리하기" 라는 제목으로 작성하였다.

학습한 내용을 온전히 내 것으로 만들기 위해선 반드시 나의 언어로 작성해야 내 것이 되고, 차후에 정리한 내용을 다시 봤을 때도 금방 기억을 더듬을 수 있을 것 이다.

그래서 나는 텍스트 보다 코드로 봤을 때의 이해도가 더 빠르기 때문에 SOLID 원칙의 내용을 정리할 때 불필요한 텍스트를 줄이고 코드로 내용을 정리하였다.

🏃 돌아보며..

위에서도 언급했지만, 항해 플러스 백엔드 스터디 2개도 병행하고 있어 참여를 망설였지만.. 신청하기 잘한 것 같다.

(2기가 마지막이 될까봐 조마조마 했던 1인.. 우빈님 감사합니다.. 🙇‍♂)

온라인 밋업을 통한 우빈님과 소통하는 것도 그렇고..

여러가지 미션의 내용도 단조롭지 않고 수준이 높은 것 같아 다시 한번 메타인지를 경험하게 해준다.

강의의 경우, 시간상 처음부터 끝까지 다시 보지는 못하겠지만.. 불과 몇 개월 전 수강한 강의임에도 단어들이 어색하다... 😂

어색했던 부분은 다시 강의를 보며 이해하고 보완하였다.

image

읽기 좋은 코드를 작성하기 위해 학습한 내용을 기반으로 적절한 추상화를 적용하는 훈련을 하며 내 코드가 읽기 좋은 코드가 되도록 노력해야겠다.

 

[출처]

 

인프런 워밍업클럽 백엔드 3기 발자국

답변 0