
워밍업 클럽 3기 BE 클린코드&테스트 - 1주차 발자국
🐾 발자국
워밍업 클럽 3기 BE 클린코드 & 테스트 - 1주차를 듣고 작성하는 발자국입니다
이번에 들은 강의 바로 가기 ⬇
📃 회고
[워밍업 클럽을 듣게 된 이유]
대학교 개강을 앞두고 있던 와중 ,,, 개강하면 열심히 살아야겠다는 다짐을 하던 와중
인프런 워밍업 클럽을 모집한다는 메일을 발견하게 되었습니다
지금까지 인프런에서 강의를 완강하려면 거의 3~4개월이 필요했던 저는
이번 기회를 통해서 공부 습관을 다잡고 하루를 알차게 살아보자라는 생각에
강의를 결제하고 워밍업 클럽을 신청하게 되었습니다.
[워밍업 클럽 1주차를 들으며 .. ]
박우빈 코치님이 짜주신 커리큘럼을 따라서 강의를 듣자는 목표를 세웠습니다.
OT 를 참가했을 때 우리가 진행하는 커리큘럼이 굉장히 빡셀 수도 있다라는
코치님의 말을 들으면서 내가 할 수 있을까 ,,,, 🧐 라는 생각도 잠시
실제로 들어보니깐 힘들긴 했지만 그래도 못들을 정도의 학습량은 아니더라고요 !
✔ 커리큘럼이 짜여져 있고
✔ 강의를 듣는 사람들이 여러명이고
✔ 미션을 통해 강의 내용을 중간중간 확인할 수 있고
✔ 강의 내용이 좋아서
더욱 열심히 들었습니다 !!
이론으로 듣고 실제 코드를 고쳤을 때의 희열도 있었던 것 같아요 ㅎㅎ
👍 1주차에서 잘한 점
날마다 정해진 강의량을 들은 것
미션을 빼먹지 않고 참여한 것
👎 1주차에서 못한 점
강의를 듣고 난후 나만의 언어로 바꿔서 복습하지 않은 것
🥅 2주차의 목표
강의를 모두 들은 후 나만의 언어로 정리해 내 걸로 만들기 !
📺 강의 내용 정리
섹션2 추상 (抽象)
우리가 클린코드를 추구하는 이유
우리는 가독성을 위해서 클린 코드를 추구한다.
가독성이 좋아지면 얻을 수 있는 것들이 많다. (이해가 잘되고, 유지보수하기 수월함)
클린 코드를 추구하기 위해서 가장 중요한 주제가 바로 추상
추상과 구체
중요한 정보는 가려내어 남기고, 덜 중요한 정보는 생략하여 버리는 것이 추상
인간은 자연스럽게 추상화 능력을 가지고 있다
'잘못된 추상화'는 굉장히 큰 사이드 이펙트를 가져오지만
'적절한 추상화' 는 해당 도메인의 문맥 안에서 정말 중요한 핵심 개념만을 남겨서 표현함으로서 굉장히 큰 이점을 얻을 수 있다.
이름 짓기
이름을 짓는다는 건 추상적 사고를 기반으로 한다
단수와 복수를 구분하기 / 이름 줄이지 않기 / 은어, 방어 사용하지 않기 / 좋은 코드를 보고 습득하기
메서드와 추상화
잘 쓰여진 코드라면 한 메서드의 주제는 반드시 하나다.
메서드의 이름은 구체적인 내용을 추상화해서 잘 나타내야 한다
생략할 정보와 의미를 부여하고 드러낼 정보를 잘 구분해야 한다
메서드 선언부
반환타입 메서드명 ( 파라미터 )
가 메서드 선언부반환타입, 메서드명, 파라미터에 추상화된 정보를 잘 담아야 한다
추상화 레벨
메서드로 추출한 경우 메서드 내부와 외부로 경계가 생긴다
각각의 세계에서는 추상화 레벨이 동등해야 한다
섹션3 논리, 사고의 흐름
뇌 메모리 적게 쓰기
최소한의 인지로 최대한의 효율을 내자
뇌의 메모리에 적은 정보를 올릴수록 읽기 쉬운 코드가 된다
Early return
if - else if - else 를 사용하는 경우 else 까지 오게 되면 If, else if 의 내용을 기억하고 있어야 한다
이렇게 복잡한 코드를 사용하는 것이 아닌 조건문이 끝날 때마다 return 을 하게 되면 앞의 코드를 신경쓰지 않아도 된다
사고의 depth 줄이기
중첩 분기문, 중첩 반복문을 사용하면 사고의 depth 가 굉장히 깊어진다
무조건 1 depth 로 만드는 것이 아니라 추상화를 통한 사고 과정의 depth 를 줄이는 것이 중요하다
공백 라인을 대하는 자세
공백 라인도 의미를 가진다
복잡한 로직의 의미 단위를 나누어 보여줌으로써 읽는 사람에게 추가적인 정보를 전달할 수 있다
부정어를 대하는 자세
부정어구를 쓰지 않아도 되는 상황인지를 체크하고
부정의 의미를 담은 다른 단어가 존재하는지 고민하거나 부정어구로 메서드명을 구성한다
해피 케이스와 예외 처리
사람은 해피 케이스에만 몰두하는 경향이 있지만 예외처리를 꼼꼼히 할수록 더욱 좋은 개발자가 된다
예외가 발생할 가능성을 낮추고, 의도한 예외와 예상하지 못한 예외를 구분하자
항상 NullPointException 을 방지하는 방향으로 개발해야 한다
Optional 은 비싼 객체이기 때문에 꼭 필요한 상황에서 반환타입에 사용한다.
섹션 4 객체 지향 패러다임
추상의 관점으로 바라보는 객체 지향
객체 지향 : 객체를 통해 객체간의 협력으로 프로그래밍
객체 : 추상화 된 [데이터 + 코드]
관심사를 분리해 관심사를 한 곳으로 모으면 유지보수에 도움이 된다
객체 설계하기
관심사가 퍼져 있는 코드에서 관심사를 한 곳으로 모다 객체로 분리해야 한다
분리된 객체에서 공개 메서드를 통해서 기능을 제공한다
객체의 책임이 나뉨에 따라 객체간의 협력이 강조된다
새로운 객체를 만들때에는 1개의 관심사로 명확하게 책임이 정의되었는지 확인한다
SRP (단일 책임 원칙)
하나의 객체는 하나의 책임만 가져야 한다
관심사를 분리해서 높은 응집도, 낮은 결합도
OCP (개방-폐쇄 원칙)
확장에는 열려있고, 수정에는 닫혀있어야 한다
추상화와 다형성을 활용해 OCP 를 지킬 수 있다
LSP (리스코프-치환 원칙)
상속 구조에서 자식 클래스는 부모 클래스의 책임을 준수해야한다
ISP (인터페이스 분리 원칙)
클라이언트는 자신이 사용하지 않는 인터페이스에 의존해선 안된다
DIP (의존성 역전 원칙)
상위 수준의 모듈은 하위 수준의 모듈에 추상화로 의존해야 한다
섹션 5 객체 지향 적용하기
상속과 조합
상속보다는 조합을 사용해야 한다.
상속은 시멘트처럼 굳어지는 구조이기 때문에 수정이 어렵다
Value Object
기본타입을 객체로 감싸서 의미를 부여하고 추상화하는 기법
값으로 취급하기 위해서 불변성, 동등성, 유효성 검증 등을 보장해야 한다
Entity 는 식별값으로 객체를 비교하지만, VO 는 내부의 모든 값이 같아야 같은 객체로 취급
✔ 미션
DAY2 미션 - 추상과 구체의 예시
미션내용 : "추상과 구체" 강의를 듣고, 생각나는 추상과 구체의 예시가 있다면 한번 3~5문장 정도로 적어봅시다.
미션 수행 내용
추상
스타벅스에서 음료를 테이크아웃한다
구체
스타벅스 앱에 접속한다
주문할 매장을 선택한다
픽업 옵션에서 To-go 를 선택한다
슈크림라떼를 선택한 뒤, 원하는 옵션을 추가한다
결제 방식을 선택한 후 결제를 완료한다
매장에 도착해 주문 번호가 호출될 때까지 기다린다.
슈크림라떼를 테이크아웃한다
DAY4미션1 - 코드 리팩토링
미션 내용 : 아래 코드와 설명을 보고, [섹션 3. 논리, 사고의 흐름]에서 이야기하는 내용을 중심으로 읽기 좋은 코드로 리팩토링해 봅시다.
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 boolean validateOrder(Order order) {
if (order.isEmptyOrder()) {
showInfoLog("주문 항목이 없습니다.");
return false;
}
if (order.isNotHaveCustomerInfo()) {
showInfoLog("사용자 정보가 없습니다.");
return false;
}
if (order.isNotValidPrice()) {
showInfoLog("올바르지 않은 총 가격입니다.");
return false;
}
return true;
}
private void showInfoLog(String msg) {
log.info(msg);
}
Order 객체 내부에 isEmptyOrder, isNotHaveCustomerInfo, isNotValidPrice 메서드를 만들어서 Order 에 대한 행동을 Order 자체에서 제어할 수 있도록 구현
isEmptyOrder : 주문이 비었는지 아닌지 확인
isNotHaveCustomerInfo : 사용자 정보가 비었는지 확인
isNotValidPrice : 올바르지 않은 총 가격인지 확인
DAY4미션2 - SOLID
미션 내용 : SOLID에 대하여 자기만의 언어로 정리해 봅시다.
미션 수행
S (단일책임원칙)
각 객체가 하나의 명확한 관심사(책임)만을 가져야 한다
책임을 발견해내는 것은 경험의 영역이기 때문에 객체를 설계할 때마다 현재 객체가 하나의 책임만 가지고 있는지 질문해야 한다
ex) MinesweeperGame -> Minesweeper 랑 GameApplication 으로 분리
O (개방-폐쇄원칙)
확장에는 개방되어 있고, 수정에는 폐쇄되어야 한다
새로운 요구사항이 발생되었을 때에도 기존 코드를 직접 수정하지 않고, 확장할 수 있는 방식으로 설계해야 한다
ex) 결제 수단을 여러 개 추가해야 하는 경우
L (리스코프 치환 원칙)
상속구조에서 부모클래스를 자식클래스로 치환할 수 있어야 한다
부모클래스에서 사용하는 기능을 자식클래스가 사용하지 않는다면 추가적인 코드 처리가 필요하게 되는데, 이런 경우 사이드 이펙트가 발생할 수 있다
ex) Animal 클래스에 fly 메서드가 있는데 Animal 을 상속받는 동물이 사자인 경우
I (인터페이스 분리 원칙)
인터페이스의 단위를 잘게 쪼개 클라이언트가 사용하지 않는 기능을 사용하지 않도록 해야 한다
인터페이스에 클라이언트가 사용하지 않는 기능이 포함되어 있으면 사용하지 않는데 추가적인 코드 작업을 해야하고, 클라이언트 입장에서는 해당 메소드의 의미를 모르게 된다
ex) Animal 인터페이스에 fly() 랑 walk() 메서드가 있으면 Fly 인터페이스, Walk 인터페이스 로 분리
D (의존성 역전 원칙)
상위 수준 모듈은 하위 수준 모듈의 추상화에 의존해야 한다
상위 수준 모듈이 하위 수준 모듈의 구체적인 코드를 알 필요가 없다. 추상화를 통해 어떤 기능을 제공하는지만 알려주고 내부적인 코드는 하위 수준 모듈들에서 작성할 수 있도록 해야 한다
상위 수준 모듈인 음식점의 경우 하위 수준 모듈로 라면끓이는 법을 아는게 아니라 음식만드는 법이라는 추상화에 의존하면 여러 메뉴를 만들 수 있음
댓글을 작성해보세요.