🎁 모든 강의 30% + 무료 강의 선물🎁

워밍업 클럽 3기 BE 클린코드&테스트 - 2주차 발자국

Day 6

섹션6. 코드 다듬기

주석의 양면성

주석이 많다는 것은 우리의 비즈니스 요구사항을 잘 못 녹였다는 것

후대에 전해야 할 “의사결정의 하스토리” 같은 도저히 코드로 표현할 수 없을 때 주석을 달자

주석도 작성하는 순간 관리주체가 되고 버전이 생긴다.

꼭 잊지말고 업데이트하자.

변수와 메서드의 나열 순서

나열 순서로도 의도와 정보를 전달할 수 있다는 것

변수는 사용하는 순서대로

메서드는 공개 메서드를 상단 비공개는 하단

메서드도 기준을 가지고 배치하자.

상태 변경 >> 판별 ≥ 조회

리팩토링을 하면 두가지를 신경쓰자

  1. 이 메서드 어디둘까?

  2. 얘 공개인가, 비공개인가?

패키지 나누기

패키지는 문맥으로써의 정보를 제공할 수 있다.

처음 만들 때부터 잘 고민해서 패키지를 나눠놓는 것이 제일 좋다.

기능 유지보수하기 (1) - 버그 잡기

추상화를 통해 책임을 단위로 잘 쪼개면

변경해야하는 부분이 최소화된다.

기능 유지보수하기 (2) - 알고리즘 교체하기

dfs - 재귀, 스택

재귀를 많이 호출하면 스택오버플로우가 발생한다.

처음에는 row, col을 따로 관리했기때문에 재귀를 호출해야했지만

CellPosition이라는 개념을 도입하면서 하나로 관리할 수 있게 되면서

stack을 사용할 수도 있게 되었다.

이렇게 클린코드 리팩토링을 통해서 생각의 전환도 해볼 수 있다

IDE의 도움 받기

결국 모든건 다 가독성을 위한 것

코드 포맷 정렬 Option + Cmd + L

포맷 규칙: .editorconfig

https://EditorConfig.org

Day 7

미션진행

Day 8

섹션7. 리팩토링 연습

연습 프로젝트 소개

리팩토링 포인트

  • 추상화 레벨

  • 객체로 묶어볼만한 것은 없는지

  • 객체지향 패러다임에 맞게 객체들이 상호 협력하고 있는지

  • SRP

  • DIP

  • 일급 컬렉션

리팩토링 한 단계마다, 그 이유를 설명할 수 있어야 한다.

리팩토링 (1) - 추상화 레벨

리팩토링 (2) - 객체의 책임과 응집도

리팩토링(1)에서는 메서드 레벨에서의 추상화였다면

리팩토링(2)에서는 객체 레벨에서의 추상화

리팩토링 (3) - 관점의 차이로 달라지는 추상화

외부에 있는 어떤 데이터를 필요로 해서 가져온다고 했을 때

두 가지 관점으로 생각해볼 수 있다.

  1. 어떤 데이터를 필요로 하는가?

  2. 데이터를 어디로부터 어떻게 가져올 것인가?(방법)

섹션8. 기억하면 좋은 조언들

능동적 읽기

내가 이해할 수 있도록 수단과 방법을 가리지 말자

핵심목표는 우리의 도메인 지식을 늘리고 이전 작성자의 의도를 파악하는 것이다

오버 엔지니어링

필요한 적정 수준보다 더 높은 수준의 엔지니어링은 좋지않다.

은탄환은 없다

지속 가능한 소프트웨어의 품질 vs 기술 부채를 안고 가는 빠른 결과물

대부분의 회사는 돈을 벌고 성장해야 하고, 시장에서 빠르게 살아남는 것이 목표다.

이런 경우에도, 클린 코드를 추구하지 말라는 것이 아니라,

미래 시점에 잘 고치도록 할 수 있는 코드 센스가 필요하다.

결국은, 클린 코드의 사고법을 기반으로 결정하는 것

도구라는 것은, 일단 그것을 한계까지 사용할 줄 아는 사람이 그것을 사용하지 말아야 할 때도 아는 법이다.

적정 수준을 알기 위해, 때로는 극단적으로 시도해보자.

섹션9. Outro

추상과 구체를 인식뿐 아니라 넘나들 수 있어야 한다

Day 9

Practical Testing: 실용적인 테스트 가이드

섹션1. Intro

강의소개

메타인지가 중요하다.

채용 시 구현 과제 등에서 테스트 작성여부, 테스트 코드 구현방식을 확인하는 만큼

주니어 개발자에게 가장 기대하는 요소 중 하나이다.

섹션2. 테스트는 왜 필요할까?

테스트는 왜 필요할까?

빠른 피드백, 자동화, 안정감

올바른 테스트 코드로 이익을 만들어내자

섹션3. 단위 테스트

테스트 케이스 세분화하기

이 요구사항이 과연 실제 내가 구현할 때 그 요구사항과 정확히 맞아떨어지는가

암묵적이어서 얘기를 안한 것이 있거나,

도출이 안된,

드러나지 않은 요구사항이 있는지 항상 염두에 두고 고민을 해야한다.

예를 들어, 한 종류의 음료 여러 잔을 한 번에 담는 기능이라고 했을 때

0이나 1이 들어왔을 때 어떻게 할것인지

테스트하기 어려운 영역을 분리하기

현재 날짜/시간, 랜덤 값, 전역 변수/함수, 사용자 입력 등

표준 출력, 메시지 발송, 데이터베이스에 기록하기 등 을 최대한 외부로 밀어내고 주입받자.

섹션4. TDD: Test Driven Development

Test Driven Development

선 테스트 작성 후 기능 구현을 한다면,

복잡도가 낮은(유연하며 유지보수가 쉬운), 테스트 가능한 코드로 구현할 수 있게 한다.

쉽게 발견하기 어려운 엣지(Edge) 케이스를 놓치지 않게 해준다.

구현에 대한 빠른 피드백을 받을 수 있다.

과감한 리팩토링이 가능해진다.

섹션5. 테스트는 [ ]다

테스트 코드는 문서다

프로덕션 기능을 설명하는 테스트 코드 문서

다양한 테스트 케이스를 통해

프로덕션 코드를 이해하는 시각과 관점을 보완

어느 한 사람이 과거에 경험했던 고민의 결과물을

팀 차원으로 승격시켜서, 모두의 자산으로 공유할 수 있다.

DisplayName을 섬세하게

~테스트 대신 ~ 할 수 있다

명사의 나열보다 문장으로

테스트 결과까지 기술하면 더 좋다

BDD 스타일로 작성하기

given, when, then에 맞추어 DisplayName에 명시하자

미션

Day 7

[섹션 7. 리팩토링 연습]의 "연습 프로젝트 소개" 강의를 보고, '스터디 카페 이용권 선택 시스템' 프로젝트에서 지금까지 배운 내용을 기반으로 리팩토링을 진행해 봅시다.

오늘 1차 리팩토링을 마치고, 다음날 자고 일어나서 다시 한번 내가 리팩토링한 코드를 살펴봅니다. 자고 일어나서 뇌가 맑아지면 새로운 시야가 열릴 때가 많거든요. 만약 추가로 수정하고 싶은 부분이 보인다면, 2차 리팩토링을 진행합니다.

Day7 미션 - 1차 리팩토링

일급 컬렉션을 사용해서 Passes, LockerPasses를 만들었다.

필터 로직을 일급 컬렉션 내부에 등록했다.

DIP를 적용해 StudyCafePassMachine이 인터페이스를 의존하게 만들었다.

확장성을 위해 InputHandler, OutputHandler, ~ListHandler를 만들었다.

StudyCafeFileHandler의 매직 스트링을 추출하였다.

OutputHandler에 showExceptionMessage를 만들어 showSimpleMessage와 차별점을 두었다.

ConsoleInputHandler의 사용자 입력에 대한 예외처리를 했다.

StudyCafePass, StudyCafeLockerPass를 묶어서Order로 만들 수 있을 것 같아서 일단 만들어두었다.

두 객체의 중복으로 있는 passType, duration, price, display()가 너무 거슬린다.

사물함의 사용여부에 따라 분기가 되는데 StudyCafeLockerPassType을 만들어서 한번에 처리해보고 싶은데 방법이 떠오르지 않는다.

머리를 비운 후 2차 리팩토링을 진행해봐야겠다.

중간점검

역시 스터디를 하길 잘했다는 생각이 든다.

다른 사람들이 리팩토링 한 코드를 보면서 배울점이 많았고,

나는 우물안 개구리임을 깨달았다.

더 열심히 해야겠다 파이팅

댓글을 작성해보세요.


채널톡 아이콘