[워밍업 클럽 2기 BE 클린코드&테스트] - Readable Code 발자국 1주차
강의 정리
Section 1
쓰기 좋은 코드 << 읽기 좋은 코드
코드를 잘 짠다? 읽기가 좋다~
도메인 : 해결하고자 하는 문제 영역
도메인 지식 : 도메인을 이해하고 해결하는데 필요한 지식
Section 2
클린 코드의 본질은 : 가독성
프로그램 : 데이터 + 코드
추상과 구체
추상화의 대표적인 행위 : 이름 짓기
적절한 추상화는 코드를 이해하기 쉽게 + 구체를 쉽게 유추
적절한 추상화는 도메인의 문맥 안에서 중요한 정보는 가려내어 남긴다
이름 짓기
단순하지만 고도의 추상화 행위! 굉장히 중요하다!!
1. 단수, 복수 표현하기
2. 이름 줄이지 않기
줄임말 : 가독성이 나빠진다
관용적으로 사용하는 줄임말 정도는 사용해도 괜찮다
Ex) column -> col, latitude -> lat, longitude -> lon
3. 은어/방언 사용하지 않기
일부만 이해하는 용어 금지X (새로운 팀원을 위하여)
도메인 용어 사용하기
도메인 : 해결하고자 하는 문제 영역
4. 좋은 코드를 보고 습득하기
좋은 프레임워크, 라이브러리들의 좋은 설계나 코드를 보고 학습하자!
메서드와 추상화
잘 쓰여진 코드라면, 한 메서드의 주제(기능)는 반드시 하나!
메서드의 이름으로 구체적인 내용을 추상화
⭐ 메서드 선언부
반환타입 + 메서드 시그니처 = 메서드 선언부
메서드 시그니처 : 메서드명 + 파라미터
메서드 시그니처라는 용어는 오버로딩 때문에 따로 정리된 용어라고 한다
메서드명
기능을 유추할 수 있는 적잘한 이름 (파라미터와 연결지어 풍부하게 유추!)
파라미터
타입, 개수, 순서를 통해 의미 전달!!
외부와 소통하는 창 (필요한 정보를 의미한다!)
반환타입
메서드 시그니처에 적절한 반환값 -> 테스트에 좋을 수 있다
실습Tip
파라미터와 연결지어 풍부하게 유추
//cellInputCol로부터 Col을 변환할꺼야
int selectedColIndex = convertColFrom(cellInputCol);
매직넘버, 매직 스트링
아직 상수로 추출되지 않은 값
이름을 짓고 의미를 부여 -> 가독성, 유지보수성 향상
Section 3
논리, 사고의 흐름!
범주화를 통한 최소한의 정보로 나타내어 추상화, 가독성을 향상시키자!
Early return
if 문을 메서드로 분리!
if문에 return을 사용 -> 이전 정보를 신경 쓰지 않아도 된다!
Early return을 통해 else의 사용을 지양
depth 줄이기
중첩 분기문, 중첩 반복문(실제 동작을 줄이는 것 X, 코드를 분리하는 것 O)
무조건 1depth? 아니다!
이해하기 편하다면 나누지 말자 -> 가독성을 기준으로 분리하자
실습Tip
컴파일 에러를 줄이기 위해서 메서드를 복사해서 리팩토링한다!
공백 라인을 통해 의미 단위를 나누자!
부정어
추가로 사고를 뒤짚어야 하므로 불편할 수 있다
왼쪽이 아니다
오른쪽이다로 변경! (부정어 없이 다른 표현으로 작성한다면 👍)
또는, 메서드명에 부정의미를 담아서 작성하자
해피 케이스와 예외처리
예외 발생 가능성 낮추기
검증이 필요한 부분은 외부의 데이터 (사용자 데이터는 믿으면 안된다!)
의도한 예외, 예상하지 못한 예외 구분하기
NULL
NullPointException 방지
return null 자제
Optional
코스트가 크다
Optional을 파라미터로 받지 않도록 한다
케이스가 3개나 된다
Optional이 null인지 아닌지 + Optional이 null인지
반환타입에만 사용한다
null일 가능성이 있다는 것을 알려줄 때 사용하고
Optpional을 반환받았다면 빠르게 해소한다
Optional 해소하는 방법
orElseGet(), orElseThrow(), ifPresent(), ifPresentOrElse()
orElse() -> 항상 실행
orElseGet() -> null인 경우 실행
public T orElse(T other) {
return value != null ? value : other;
}
public T orElseGet(Supplier<? extends T> supplier) {
return value != null ? value : supplier.get();
}
public T orElseThrow() {
if (value == null) {
throw new NoSuchElementException("No value present");
}
return value;
}
Section 4 객체 지향 패러다임
객체 : 추상화된 데이터 + 코드
협력과 책임
관심사의 분리 : 높은 응집도, 낮은 결합도
객체 설계하기
1개의 관심사로 명확하게 책임이 정의되었는지!
생성자, 정적 팩토리 메서드에서 유효성 검증 가능 (도메인 특화 검증 로직)
setter 사용 자제
why?
객체 내부에서 외부의 개입 없이 자체적인 변경/가공
만약 외부데이터로 변경해야한다면? update~로 네이밍을 하자
getter 도 추천 X
필드의 수는 적을수록 좋다
필드를 가공해서 계산할 수 있다면 메서드를 통해 제공하도록 하자!
성능판단
SOLID
1. SRP : Single Responsibility Principle
단일 책임 원칙
하나의 클래스는 단 한가지의 변경 이유(책임)만을 가져야 한다.
객체가 가진 공개 메서드, 필드, 상수 등은 단일 책임에 의해서만 변경되는가?
관심사의 분리
높은 응집도, 낮은 결합도 (의존성 낮다)
2. OCP : Open - Closed Principle
개방 - 폐쇄 원칙
확장에는 열려 있고, 수정에는 닫혀있다
기존 코드의 변경 없이, 시스템의 기능을 확장할 수 있다
추상화와 다형성을 활용해서 OCP를 지킬 수 있다
3. LSP : Liskov Substiution Principle
리스코프 치한 원칙
상속 구조에서, 부모 클래스의 인스턴스를 자식 클래스의 인스턴스로 치환할 수 있어야 한다.
LSP 를 위반하면, 상속 클래스를 사용할 때 오동작, 예상 밖의 예외가 발생하거나, 이를 방지하기 위한 불피요한 타입 체크가 동반될 수 있다.
Ex. 엑셀을 밟으면 자동차는 앞으로 나가야한다
4. ISP : Interface Segregation Principle
인터페이스 분리 원칙
클라이언트는 자신이 사용하지 않는 인터페이스에 의존하면 안된다
인터페이스를 기능 단위로 쪼개자!!
ISP를 위반하면, 불필요한 의존성으로 인해 결합도가 높아진다
5. DIP : Dependency Inversion Principle ⭐
의존성 역전 원칙
상위 수준의 모듈은 하위 수준의 모듈에 의존해서는 안 된다. 둘 모두 추상화에 의존해야 한다.
의존성의 순방향 : 고수준 모듈이 저수준 모듈을 참조하는 것
의존성의 역방향 : 고수준, 저수준 모듈이 모두 추상화에 의존하는 것
학습할 도서 목록 정리
함께 자라기』(김창준, 인사이트, 2018)
『Clean Code(클린 코드)』(로버트 C. 마틴, 인사이트, 2013)
『클린 아키텍처: 소프트웨어 구조와 설계의 원칙』(로버트 C. 마틴, 인사이트, 2019)
『최고의 프롬프트 엔지니어링 강의』(김진중, 리코멘드, 2024)
YouTube @ShuOmi_Official 'Zettelkasten Note-Taking Method: Simply Explained'
댓글을 작성해보세요.