
워밍업 클럽 3기 BE - 발자국 1주 차
1. 들어가며
원래 인프런 워밍업 클럽 스터디 1기를 신청하려고 했었는데 업무에 치이다보니 3기까지 미뤄졌네요.
테스트 코드 강의가 올라오자마자 바로 완강을 했었는데 정말 도움이 많이 돼서 꼭 한 번 인프런 워밍업 클럽 스터디를 해보자고 생각했었습니다.
이제 1주가 지났는데, 신청하길 잘했다고 생각합니다.
특히 다른 러너분들 미션을 보는데 역시 고수분들이 많더라구요?
혼자 공부하는 것 보단 같이 하는게 성장하는데 도움이 된다는 사실을 또 한 번 느꼈습니다.
2. 학습했던 내용 나만의 키워드로 작성하기
섹션 2. 추상
추상과 구체
추상으로부터 구체를 유추할 수 있어야 함
추상화 과정에서 중요한 정보를 부각시켜야 함
해석자가 동일하게 공유하는 문맥(context)이 있어야 함
즉, ‘적절한 추상화’ 는 해당 도메인의 문맥안에서, 정말 중요한 핵심 개념만 남겨서 표현하는 것
이름 짓기 / 메서드 선언부
추상화의 가장 대표적인 행위 하나를 꼽으라면 이름을 짓는 것
추상화 레벨
하나의 세계 안에서는, 추상화 레벨이 동등해야 한다.
why? 그래야 코드를 읽기가 수월함
매직 넘버, 매직 스트링
상수를 추출하는 것도 추상화 행위
섹션 3. 논리, 사고의 흐름
뇌 메모리 적게 쓰기 (인지적 경제성)
인지적 경제성은 최소한의 인지로 최대의 효율을 내보자는 의미
코드를 작성할 때도 마찬가지로 인지적 경제성을 추구하도록 작성하기
Early return
기억해야 되는 정보가 많은 상태라면 전부 기억하지 않는 방향으로 리팩토링을 하는게 효과적
사고의 depth 줄이기
무조건 1 depth로 만들기 X
추상화를 통한 사고 과정의 depth를 줄이는 것이 중요
사용할 변수는 가깝게 선언하기
공백 라인
공백 라인도 의미를 가짐
복잡한 로직의 의미 단위를 나누어 보여주는 역할
부정어
다른 도메인 표현이나 혹은 다른 영단어를 사용
정 안된다면 부정연산자를 써서 사고를 두 번 할 바에는 메서드 자체에 그냥 부정의 의미 (is not, does not, never 등등)를 담는 식으로 활용
해피 케이스, 예외 처리
예외가 발생할 가능성을 낮추는 것이 가장 중요
의도한 예외와 예상 하지 못한 예외를 구분하기가 중요
섹션 4. 객체 지향 패러다임
객체, 협력과 책임, 관심사의 분리, 높은 응집도와 낮은 결합도
관심사에 따라 객체를 분리하게 되면 각 객체는 특정한 관심사로만 이루어짐
특정한 관심사로 이루어진 객체는 높은 응집도를 가지며 다른 객체와 협력할 때 낮은 결합도를 가짐
getter/setter 자제하기, 객체에 메시지 보내기
setter는 최대한 지양하기
getter를 남발하는 건 무례하면서 폭력적인 행위
공개 메서드를 통해 객체끼리 협력하기
SOLID: SRP, OCP, LSP, ISP, DIP
SRP
변경이 있을 때 파급 효과가 적어야 한다.
변경이 있을 때 하나의 클래스, 하나의 지점만 고쳐야 한다.
OCP
인터페이스를 구현한 새로운 클래스를 하나 만들어서 새로운 기능을 구현
인터페이스를 구현한 새로운 클래스를 만드는 것은 기존 코드를 변경한게 아니라 확장에는 열려 있고 변경에 닫혀 있다.
LSP
하위 클래스는 인터페이스 규약을 다 지켜야 한다.
하위 클래스를 대신 사용하더라도 의도대로 동작해야 한다.
ISP
하나의 범용적인 인터페이스보다 적당히 분리된 인터페이스 여러개가 낫다.
DIP
구현체를 바라보지 말고 인터페이스를 바라봐야한다.
추상화에 의존해야지 구체화에 의존하면 안된다.
DI/IoC
IoC
내가 호출하는게 아니라 프레임워크 같은게 대신 호출
DI
의존 관계 '주입'
섹션 5. 객체 지향 적용하기
상속과 조합
조합을 활용하는 것이 더 좋은 설계
why? 상속은 결합도가 높기 때문
Value Object, Entity
VO는 도메인의 개념을 추상화한 객체, 불변성, 동등성, 유효성 검증을 보장해야 함
Entity는 식별자가 존재하며, 식별자가 같으면 동등한 객체로 취급
일급 컬렉션
컬렉션으로 Wrapping한 객체를 뜻
Enum
상수의 집합, 상수들에 대한 로직을 담을 수 있음
추상화와 다형성 활용하여 반복되는 if문 제거. OCP 지키기
OCP를 지기키 위해서 변화하는 것과 변하지 않는 것을 구분해서 생각해야 함
변하는 것
조건 & 행위 (= 구체)
변하지 않는 것
조건을 만족하는가? / 행위를 수행한다. (= 추상)
숨겨져 있는 도메인 개념 도출하기
도메인 지식은 만드는 것이 아니라 발견하는 것
3. 학습 회고
평범한 기업에서 소위 말하는 좋은 코드를 작성하는 개발자는 생각보다 희귀한 것 같습니다.
아쉽게도 시간에 쫓기기 때문이겠죠. 저 역시 시간이 없어 기능 구현만 마무리하고 리팩토링은 뒤로 미루는 경험을 했었고, 지금도 하고 있습니다.
후에 리팩토링을 하면 좋겠지만 대부분의 개발자들은 뒤를 돌아볼 시간이 없죠.
그래서 혼자 리팩토링을 하더라도 좋은 코드를 보고 배울 기회가 굉장히 적습니다.
결국 혼자 보는 시야는 한계가 있기 때문에 어느 순간 갇히는 느낌을 받죠.
강의에서는 코드를 순차적으로 바꿔나갑니다.
메서드 명부터 SOLID를 적용하는 법까지 어떤 코드가 좀 더 나은 코드인지 방향을 제시하죠.
그래서 시야가 넓어진 느낌을 받았습니다.
다른 사람이 작성한 코드를 볼 수 있었기 때문이죠. 객체 지향 언어만 사용한 코드가 아니라 객체 지향으로 작성한 코드를요.
기회가 있을 때마다 조금씩 적용을 해볼 생각입니다. 그래서 추상화를 적용해 읽기 좋은 코드가 되도록 노력해야겠습니다. 😄
4. 미션 회고
미션 Day 2
강의를 듣기 전 미션부터 확인을 했습니다.
미션을 보자마자 '책'이 좋은 예시라고 생각했었는데 강의에서 바로 언급해서.. 😂
무슨 예시가 있을까 생각하다가 사실 추상과 구체는 거의 모든 곳에서 사용된다고 결론을 내렸습니다.
보통 어떤 행동을 한 후에 자세하게 말을 하는 경우보단 간략하게 의도만 파악하도록 말하기 때문이죠.
그래서 음식을 먹는 행동을 예시로 미션을 제출했습니다.
미션 Day 4
미션 코드를 보자마자 코드가 씁.... 물론 실무에는 이것보다 정도가 심한 코드도 훨씬 많긴 합니다.
중복 분기문과 부정 연산자를 포함한 조건식을 리팩토링해서 한 눈에 보이도록 처리했습니다.
추가로 개인적으로도 Early return은 코드를 깔끔하게 만들어준다고 생각합니다. 저도 실무에서 코드를 작성할 때 else문을 잘 쓰지 않게 되더라구요.
하지만 글을 쓰면서 아쉽다는 생각을 했습니다.
"Order 객체 안에서 검증 로직을 처리할까?"하다가 미션의 의도에 벗어나나 싶어서 메서드만 작성했는데요,
회고를 작성하면서 미션을 다시 읽어보니 원하는 것은 Order를 파라미터로 넘겨서 처리하는 게 아니라 Order 객체 안에서 검증로직을 만들라는 것 같다는 생각이 들었네요.
SOLID에 대하여 자기만의 언어로 정리하기는 개인적으로 의미가 있던 미션이였습니다.
좋은 코드를 작성하기 위해서 계속 SOLID에 대한 고민을 하고 있었거든요.
머릿속으로 생각만 하고 있었는데 글로 정리를 하니까 좀 더 선명해지는 느낌을 받았습니다.
그리고 강의의 리팩토링되는 코드를 보면서 제가 생각했던 방향과 얼추 맞았다고 보여져서 다행이였습니다. 😃
댓글을 작성해보세요.