[워밍업 클럽 4기 백엔드] 1주차 발자국
Readable Code: 읽기 좋은 코드를 작성하는 사고법 강의를 수강하고 작성한 회고입니다.
1. 학습한 내용
📍추상
클린 코드가 중요한 이유가 뭘까
가독성이 좋아진다.
즉, 시간과 자원이 절약된다.
클린 코드에서 가장 중요한 건
추상화
이다.
그럼 추상화는 무엇일까
구현 세부사항은 감추고, 중요한 정보만 남긴다.
즉, ''어떻게"할지는 숨기고, "무엇"을 할지는 보여준다.
그렇기 때문에 추상은 구체에 기반해서 생긴다.
추상화의 가장 대표적인 행위는 '이름짓기'이다.
이름 짓기
'이름'이 중요한 이유는
그럼 이름은 어떻게 지어야 할까
단수인지 복수인지 생각하기
관용어처럼 쓰는 말이 아니라면, 줄임말 사용하지 않기
도메인 용어 사용하기
좋은 코드에서 어떻게 이름이 지어지는지 보기
메서드
메서드 이름, 파라미터, 반환 타입으로 구체적인 내용을 추상화할 수 있어야 한다.
매직 넘버, 매직 스트링
의미가 불분명하고 어떤 기준으로 쓰이는 지 알기 어려운 숫자나 문자열을 매직 넘버, 매직 스트링이라고 한다.
상수로 추출해서 어떤 의미를 쓰이는지 잘 나타낼 수 있는 이름을 부여해야 한다.
📍논리, 사고의 흐름
Early return
Early return으로 else 및 switch 사용을 지양해야 한다.
사고의 depth 줄이기
중첩 분기문, 중첩 반복문을 사용할 때 추상화를 통한 사고 과정으로 depth를 줄이자.
무조건 1 depth 줄이자는 건 아님!
공백 라인
공백 라인도 의미를 가진다.
부정어구
부정어구가 쓰지 않아도 되는 상황인지 생각해보고, 메서드명으로 부정을 표현하자.
해피 케이스와 예외 처리
사용자에게 보여줄 예외와, 개발자가 보고 처리해야 할 예외를 구분해야 한다.
Optional은 비싼 객체이기 때문에 최대한 지양하고, 만약 사용해야 한다면 빠르게 해소해야 한다.
e.printStackTrace() 사용을 지양하고, 로그 시스템을 통해서 로그를 남기자.
📍객체 지향 패러다임
객체로 추상화하기
공개 메서드 선언부를 통해 외부 세계와 소통한다.
관심사가 하나의 객체로 모이기 때문에 유지보수성이 올라간다.
그래서 새로운 객체를 만들 때는 하나의 관심사로 명확하게 책임을 정의하고 있는지를 생각해야 한다.
getter/setter 사용을 지양하자.
SOLID
SRP: Single Responsibility Principle
하나의 클래스가 하나의 책임을 가지도록 설계하자.
이렇게 설계하려면 '책임'을 볼 줄 아는 눈이 필요하다.
OCP: Open-Closed Principle
기존 코드의 변경 없이, 새로운 기능을 추가할 수 있어야 한다.
추상화와 다형성을 활용하자.
LSP: Liskov Substitution Principle
상속 구조에서, 자식은 부모를 대체할 수 있어야 한다.
만약 자식에서 부모에는 없는 예상치 못한 예외를 던진다면
instanceOf
와 같은 불필요한 처리를 해줘야 할 수도 있다.
ISP: Interface Segregation Principle
사용하는 인터페이스에만 의존하자.
인터페이스 안에 필요하지 않은 기능이 있다면 인터페이스를 쪼개야 한다.
DIP: Dependency Inversion Principle
추상화 레벨이 높은 고수준 모듈에서 구체적인 저수준을 바로 의존해서는 안 되고, 추상화 즉, 인터페이스에 의존해야 한다.
📍객체 지향 적용하기
상속보다는 조합
상속은 부모가 변경될 때 자식이 영향을 받는다.
그래서 상속보다는 조합을 권장한다.
Value Object
값 객체란, 도메인의 어떤 개념을 추상화하여 표현한 객체
불변성을 가지고, 값 자체로 동등성을 가진다.
일급 컬렉션
일급 컬렉션이란, 하나의 컬렉션(List, Set 등)을 필드로 가지는 객체이다.
컬렉션을 직접 노출하지 않고, 객체로 감싸 의미를 부여하는 방식이다.
만약 해당 컬렉션을 반환해야 한다면, 꼭 새로운 컬렉션으로 만들어서 반환해야 한다.
Enum
Enum은 상수를 모아놓은 것이고, 그 상수와 관련된 로직을 담을 수 있다.
다형성 활용하기
복잡한 if문이 있을 때, 다형성과 OCP를 활용해서 단순하게 만들자.
📍1주차 회고
추상, SOLID 등 여러 개념들을 그동안은 단순히 정의만 외우고 정확히 알지는 못했지만, 지금은 실제 코드에서 어떻게 활용되고, 어떻게 생각하고 설계를 해야 하는지 감을 잡을 수 있게 되었다.
그리고, 일주일 동안 공부한 내용을 이렇게 발자국으로 정리한 게 큰 도움이 되었다. 직접 정리도 해보고 한 번 더 생각을 해보니 내가 어떤 걸 모르고, 어떤 부분이 부족한지 확인할 수 있었다. 앞으로도 꾸준히 발자국을 남길 생각이다.
2. 미션
코드 리팩토링 미션
해결 과정
중첩 조건문의 depth를 줄여 가독성을 개선
조건별 early return으로 흐름을 단순화시킴
조건문의 의미를 Order 내부 메서드로 만들어 메서드명 자체로 의도를 명화하게 함
부정 연산자를 사용하지 않도록
hasNoCustomerInfo()
의 네이밍으로 변경
회고
메서드명, 변수명 등 이름의 중요성을 깨달았다. 사실 이전엔 코드를 작성할 때 네이밍에 대해 엄청 깊게 고민하지 않았고, 부정연산자도 종종 사용하곤 했는데, 이번 미션으로 이름 하나만으로도 코드의 의도를 명확하게 할 수 있다는 점을 알게되었다.
출처
댓글을 작성해보세요.