![[인프런 워밍업 클럽 BE 클린코드 & 테스트 스터디] 발자국 1주차](https://cdn.inflearn.com/public/files/blogs/e5f91668-2c8d-4d30-9322-8015a78ca183/워밍업 클럽 백엔드 클린코드&테스트코드 썸네일.jpeg)
[인프런 워밍업 클럽 BE 클린코드 & 테스트 스터디] 발자국 1주차
1주차 발자국 정리
[섹션 2]
추상과 구체
추상 : 중요한 정보는 가려서 남기고, 덜 중요한 정보는 생략
추상으로부터 구체를 유추하지 못 하는 이유
추상화 과정에서 중요 정보를 부각시키지 못함
해석자가 동일하게 공유하는 문맥이 없음
적절한 추상화는 도메인 문맥 안에서, 중요한 핵심 개념만 남기는 것
이름 짓기
단수와 복수 구분
끝에 -(e)s를 붙여 데이터가 단수인지, 복수인지 구분
이름 줄이지 않기
자주 사용하는 줄임말이 이해될 수 있는 것은 문맥 때문
은어/방언 사용하지 않기
일부/현재 팀원만 아는 용어 금지
도메인 용어 사전 정의
좋은 코드 보고 습득
비슷한 상황에서 자주 사용하는 단어, 개념 습득
메서드와 추상화
한 메서드의 주제는 반드시 하나다.
생략할 정보와 의미를 부여하고 드러낼 정보를 구분
메서드 선언
메서드명
추상화된 구체를 유추할 수 있는, 적절한 의미가 담긴 이름
파라미터와 연결지어 더 풍부한 의미 전달 가능
파라미터
타입, 개수, 순서를 통해 의미를 전달
외부 세계와 소통하는 창
반환 타입
메서드 시그니처에 납득이 가는, 적절한 타입의 반환값 돌려주기
void 대신 충분히 반환할 만한 값이 있는지 고민
추상화 레벨
하나의 세계 안에서는, 추상화 레벨이 동등해야 한다.
추상화 레벨을 주변 코드와 동등하게 구성
매직 넘버, 매직 스트링
의미를 갖고 있으나, 상수로 추출되지 않은 숫자, 문자열 등
상수 추출로 이름을 짓고, 의미를 부여함으로써 가독성 및 유지 보수성이 상승한다.
[섹션 3]
뇌 메모리 작게 쓰기
인지한다는 것 자체가 메모리를 사용하는 것
추상화를 통해서 인지할 정보를 추려내기
Early Return
else문을 쓴다는 것은 이전 if문의 조건을 기억해야 하는 것
메모리 작게 쓰기의 중요성을 생각하면 이전 조건 기억을 줄여야 한다.
빠른 return문을 통해 이전 조건을 기억하지 않도록 하는 기법
사고의 depth 줄이기
중첩 분기문, 중첩 반복문
메서드 분리로 1차원 반복문으로 구성할 수 있다.
중첩 구조가 사고하는 데 도움이 된다면 메서드 분리할 필요가 없다.
사용할 변수는 가깝게 선언하기
공백 라인을 대하는 자세
공백 라인도 의미를 가진다.
복잡한 로직의 의미 단위를 나눔으로써, 읽는 사람에게 추가 정보 제공 가능
부정어를 대하는 자세
부정 연산자 코드는 가독성이 떨어지고, 생각하는 것 자체가 비효율적이다.
메서드 네이밍에 부정의 의미를 담는 것이 생각하기 더 편하다.
부정어구를 쓰지 않아도 되는 상황인지 체크
부정의 의미를 담은 다른 단어가 존재하는지 고민 or 부정어구로 메서드명 구성
해피 케이스와 예외 처리
예외가 발생할 가능성 낮추기
어떤 값의 검증이 필요한 부분은 주로 외부 세계와의 접점
사용자 입력, 객체 생성자, 외부 서버의 요청 등
의도한 예외와 예상하지 못한 예외를 구분하기
사용자에게 보여줄 예외와 개발자가 보고, 처리해야 할 예외 구분
Null을 대하는 자세 (Optional에 관하여)
Optional은 비싼 객체이다. 꼭 필요한 상황에서 반환 타입을 사용한다.
Optional을 파라미터로 받지 않도록 한다. (분기 3가지)
Optional이 가진 데이터가 null인지 아닌지 + Optional 자체가 null인지
Optional을 반환받았다면 최대한 빠르게 해소
분기문을 만드는 isPresent() - get() 대신 다른 API 사용
ex) orElseGet(), orElseThrow(), ifPresent(), ifPresentOrElse()
orElse() : 항상 실행, 확정된 값일 때 사용, 호출할 필요가 없을 도 실행
orElseGet() : null인 경우 실행, 값을 제공하는 동작 정의
orElseThrow() : null인 경우 실행, 예외 동작 정의
[섹션 4]
추상의 관점으로 바라보는 객체 지향
관심사의 분리, 높은 응집도, 낮은 결합
객체 설계하기 (1)
절차 지향에서 잘 보이지 않았던 개념을 가시화
관심사가 한 군데로 모이기 때문에 유지보수성을 상승시킨다.
객체 내부에서 객체가 가진 데이터의 유효성 검증 책임을 가질 수 있다.
여러 객체를 사용하는 입장에서는 구체적인 구현에 신경쓰지 않고, 보다 높은 추상화 레벨에서 도메인 로직을 다룰 수 있다.
새로운 객체를 만들 때, 주의할 점
1개의 관심사로 명확하게 책임이 정의되어 있는지 확인하기
생성자, 정적 팩토리 메서드에서 유효성 검증이 가능하다.
setter 사용 자제, 외부 세계 데이터로 변경해야 하는 경우, update~ 같이 의도를 드러내는 네이밍을 쓰자.
필드의 수는 적을수록 좋다.
SRP : Single Responsibility Principle (단일 책임 원칙)
하나의 클래스는 단 한 가지의 변경 이유만을 가져야 한다.
객체가 가진 공개 메서드, 필드, 상수 등은 해당 객체의 단일 책임에 의해서만 변경 되는가?
관심사의 분리
높은 응집도, 낮은 결합도
OCP : Open-Closed Principle (개방 폐쇄 원칙)
확장에는 열려 있고, 수정에는 닫혀 있어야 한다.
추상화와 다형성을 활용해서 OCP를 지킬 수 있다.
LSP : Liskov Substitution Principle (리스코프 치환 원칙)
상속 구조에서, 부모 클래스의 인스턴스를 자식 클래스의 인스턴스로 치환할 수 있어야 한다.
자식 클래스는 부모 클래스의 책임을 준수하며, 부모 클래스의 행동을 변경하지 않아야 한다.
LSP를 위반하면, 상속 클래스를 사용할 떄 오동작, 예상 밖의 예외가 발생하거나, 이를 방지하기 위한 불필요한 타입 체크가 동반될 수 있다.
ISP : Interface Segregation Principle (인터페이스 분리 원칙)
클라이언트는 자신이 사용하지 않는 인터페이스에 의존하면 안 된다.
ISP를 위반하면, 불필요한 의존성으로 인해 결합도가 높아지고, 특정 기능의 변경이 여러 클래스에 영향을 미칠 수 있다.
DIP : Dependency Inversion Principle (의존성 역전 원칙)
상위 수준의 모듈은 하위 수준의 모듈에 의존해서는 안 된다. 둘 모두 추상화에 의존해야 한다.
의존성의 순방향 : 고수준 모듈이 저수준 모듈을 참조하는 것
의존성의 역방향 : 고수준, 저수준 모듈이 모두 추상화에 의존하는 것
저수준 모듈이 변경되어도, 고수준 모듈에는 영향이 가지 않는다.
[섹션 5]
상속과 조합
상속은 시멘트처럼 굳어지는 구조, 수정이 어렵다.
조합과 인터페이스를 활용하는 것이 유연한 구조
상속을 통한 코드의 중복 제거가 주는 이점보다, 중복이 생기더라도 유연한 구조 설계가 주는 이점이 더 크다.
Value Object
도메인의 어떤 개념을 추상화하여 표현한 값 객체
값으로 취급하기 위해서, 불변셩, 동등성, 유효성 검증 등을 보장해야 한다.
불변성 : final 필드 사용, setter 금지
동등성 : 서로 다른 인스턴스여도 내부의 값이 같으면 같은 값 객체로 취급
equals() & hashCode() 재정의 필요유효성 검증 : 객체가 생성되는 시점에 값에 대한 유효성을 보장하기
Value Object vs Entity
Entity는 식별자가 존재한다. 식별자가 아닌 필드의 값이 달라도, 식별자가 같으면 동등한 객체로 취급한다.
Value Object는 식별자 없이, 내부의 모든 값이 다 같아야 동등한 객체로 취급한다.
일급 컬렉션
컬렉션을 포장하면서, 컬렉션만을 유일하게 필드로 가지는 객체
컬렉션을 추상화하며 의미를 담을 수 있고, 가공 로직의 보금자리가 생긴다.
만약, getter로 컬렉션을 반환할 일이 생긴다면, 외부 조작을 피하기 위해 꼭 새로운 컬렉션으로 만들어서 반환, new 사용
Enum의 특성과 활용
Enum은 상수의 집합이며, 상수와 관련된 로직을 담을 수 있는 공간이다.
특정 도메인 개념에 대해 그 종류와 기능을 명시적으로 표현해줄 수 있다.
만약, 변경이 정말 잦은 개념은 Enum 보다 DB로 관리하는 것이 나을 수 있다.
다형성 활용하기
인터페이스 구현을 통하여 여러 개의 구현 클래스들을 인터페이스로 관리
숨겨져 있는 도메인 개념 도출하기
도메인 지식은 만드는 것이 아니라 발견하는 것
객체 지향은 현실을 100% 반영하는 도구가 아니라, 흉내내는 것이다.
설계할 때는 근식적, 거시적 관점에서 최대한 미래를 예측하고, 시간이 지나 만약 틀렸다는 것을 인지하면 언제든 돌아올 수 있도록 코드를 만들어야 한다.
[Day2 Mission]
ㅇhttps://taey-coding.tistory.com/75
[Day4 Mission]
댓글을 작성해보세요.