이번 3주차에도 어김없이 수요일날 과제메일이 도착했다.
메일을 쭉 읽다가 잘 이해가 가지 않았다.
클래스(객체)를 분리하는 연습???????????
클래스를 어떤 기준으로 분리하지 ?
함수처럼 분리하는 것인가 ?
명확하게 이해가 되지않아서 일단 무작정 찾아보았다.
그런데 그중에서도 아래 영상에서 해답을 찾을 수 있었다.
이 아래의 글은 "[OKKYCON: 2018] 박재성 - 의식적인 연습으로 TDD, 리팩토링 연습하기" 영상을 정리한 글 입니다.
의식적인 연습이란 ?
연습을 많이 하면 실력이 높아질 것이라고 생각 끊임없이 연습, 연습, 연습
하지만 무조건 연습한다고 실력 늘지 않는다.
1차 프로그래머와 10년차 프로그래머가 있을 때 진짜 10년차 프로그래머가 프로그램 역량이 더 뛰어나다고 장담할 수 있습니까?
10년된 프로그래머가 어떤식으로 연습하고 살아왔는지에 따라서 1년차보다 못 할수도 있다 더 잘할 수도 있다.
물론 경험적인 측면에서는 10년차 프로그래머가 훨씬 더 뛰어나겠지만
프로그래머 구현하는 능력에서는 1년차 프로그래머가 뛰어날 수도 있다.
연습을 무작정하는 것보다 효과적으로 하는게 중요하다
사실 무조건 TDD와 리팩토링을 연습한다고 했을 때 실력이 늘지 않는다.
이렇게 5,6년 후에야 감이 잡힐 정도로 어려운 활동이다.
그리고 여기서 도전했다가 실패하시는 분들이 정말 많다.
그러면 어떻게하면 효과적으로 할 수 있을까?
의식적인 연습의 7 가지 원칙
- 효과적인 훈련 기법이 수립되어 있는 기술 연마
- 개인의 컴포트 존을 벗어난 지점에서 진행, 자신의 현재 능력을 살짝 넘어가는 작업을 지속적으로 시도
- 많은 사람들은 일정수준의 역량이 되면 그것에 만족하고 그 상태에서 계속 연습하려고 한다. 그게 편하니까 하지만 내가 한 단계 더 성장하려면 컴포트 존이라고 하는 즉 내각 편안한 상태를 깨는 연습이 필요하다. 그래야지만 내가 한 단계 더 성장할 수 있다. 그러다 편해지면 또 다시 깨는 연습을 하고 또 편해지면 그것을 깨는 연습을 하고하는 게 정말 중요하다.
- 명확하고 구체적인 목표를 가지고 진행
- 연습을 할 때, 그냥 아무생각없이 내가 어제 짰던 프로그램이네? 아무런 목표없이 그냥 하면 무의미하다. 똑같은 수준의 역량으로 비슷한 수준의 코드가 나온다. 따라서 연습할 때 구체적이고 명확한 목표를 가지고 연습해야 한다.
- 신중하고 계획적이다. 즉, 개인이 온전히 집중하고 '의식적'으로 행동할 것을 요구
- 피드백과 피드백에 따른 행동 변경을 수반
- 코드리뷰받을 수 있는 환경을 만들어 내가 무엇인가를 연습하고나서 바로 즉각적인 피드백을 받고 그 피드백에 따라서 다음 단계를 연습하고 이런식의 연습을 설계하는 게 상당히 중요하다.
- 효과적인 심적 표샹을 만들어내는 한편으로 심적 표상에 의존
- 기존에 습득한 기술의 특정 부분을 집중적으로 개선함으로써 반전시키고, 수정하는 과정을 수반
의식적인 연습으로 TDD, 리팩토링 연습하는 과정
프로그램 처음 시작할때는 TDD연습보다는 단위 테스트 연습부터 해라
1 단계 단위테스트 연습
내가 사용하는 api사용법을 익히기 위한 학습 테스트에서 시작
예를 들어 내가 split()이라는 기능이 어떻게 동작하는지 잘 모르겠다 라고 하면
이런식으로 split에 대한 단위테스트를 만들어서 테스트 할 수 있다.
즉 이렇게 API부터 테스트케이스를 만들어서 연습해보아라!
연습 효과
- 단위테스트 방법을 학습할 수 있다.
- 단위테스트 도구의 사용법을 익힐 수 있다.
- 사용하는 API에 대한 학습 효과가 있다.
2 단계 TDD 연습
지켜야 할 원칙
- 회사 프로젝트에 연습하지 말고 장남감 프로젝트를 활용해 연습하자.
- 웹, 모바일 UI나 DB에 의존관계를 가지지 않는 요구사항으로 연습한다.
문자열 덧셈 계산기 요구사항
쉼표 또는 콜론을 구분자로 가지는 문자열을 전달하는 경우 구분자를 기준으로 분리한 각 숫자의 합 반환
예시)
여기 단계중에 test fails와 test passes 만 즉 1,2단계까지만 연습하고 refactor은 나중에 해라
왜냐 ? 한 번에 3단계까지할려고 하면 힘들다.
2단계까지 하는 연습이 충분히 되면
그 다음에 3단계까지 연습하는 것을 추천한다.
TDD 연습해보기
먼저 이렇게 테스트 코드를 먼저 만든다.
그런뒤에 이렇게 프로덕션 코드를 만든다.
3단계 - 리팩토링 연습
리펙토링 연습 1) 메소드 분리
여기서 어디를 리팩토링을 해야할까?
한 메서드에 오직 한 단계의 들여쓰기(indent)만 한다.
else 예약어를 쓰지 않는다.
else를 안 쓰는 습관을 갖는다면 코드도 더 짧아지고 가독성도 올라간다.
또한 indent도 하나 줄어든다.
메소드가 한 가지 일만 하도록 구현하기
다시 이 코드를 보면 메서드가 한 가지 일만 하고 있을까요?
No!!
sum은 사실상 두 가지 일을 하고 있습니다.
합을 구하는 역할과 string을 number로 바꾸는 역할 이렇게 두 가지를 말이다.
리팩토링을 통해 문자를 숫자로 바꿔주는 역할과 합을 구하는 역할을 분리시켜주었다.
그런데 여기서 로컬 변수가 정말 필요한가 ?
이렇게는 할수없을까?
(오 로컬 변수를 다른 곳에서 사용 하지 않는 다면 굳이 만들지 말고 이런식으로 구성해줄 수도 있구나)
이런식으로 로컬변수가 필요한지도 계속 고민해보는 것이다.
compose method 패턴 적용
메소드(함수)의 의도가 잘 드러나도록 동등한 수준의 작업을 하는 여려 단계로 나눈다.
위 코드에서 sum과 toints는 추상화 레벨이 1이다.
하지만 text.split(",|:")) 와 if(text == null || text.isEmpty())는 추상화 레벨이 0이다.
이것을 전부 1로 맞춰주기 위해 아래처럼 해주었다.
미친것 같지만 이런식으로 compose method 패턴을 통해서 리팩토리을 할 수 있다.
이건 연습이고 장난감 프로젝트이다.
연습할때는 이렇게 극단적으로 해야한다.
그래야지 인사이트가 생긴다.
우리가 달리기 할때 모래주머니를 차고 달리듯이
과하게
그래야지 느끼는 게 있다.
그냥하던데로 하면 잘 안 느껴진다.
자 그럼 이렇게 했을 때 처음 코드를 보는 프로그래머라면 아래 코드중 어느 것이 보기 편할까?
한 번에 모든 원칙을 지키면서 리팩토링하려고 연습하지 마라.
한 번에 한 가지 명확하고 구체적인 목표를 가지고 연습해라.
리팩토링 연습 - 2) 클래스 분리
이렇게 음수를 전달하는 경우는 throw한다.
모든 원시값과 문자열을 포장한다.
모든 원시값과 문자열은 여기 value를 뜻한다.
이놈을 포장하라는 이야기는 class로 뽑으라는 이야기다
그럼 이 메소드를 클래스로 전환할 수 있다.
아래처럼 말이다.
이렇게 Positive라는 클래스를 생서하면 Positive는 0이상이라는 것이 보장이된다.
왜? 0보다 작으면 throw가 동작하니까
그래서 프로그램을 시작하는 다음부터는 string이나 int로 돌아다니는게 아니라
Positive class로 주고 받는 것이다.
그럼 이놈은 0이상이라는 값이 보장이된것이다.
훨씬 더 안전한 프로그램이 되는 것이고
그랬을 때
기능을 조금 더 추가해서 아래처럼 해줄 수 있다.
자 이렇게 한다면
이런 식으로 사용할 수 있다.
그리고 오른쪽 보면 덧셈이 add메서드로 바뀌었다.
이렇게 positive안쪽에 추가를 해준것이다.
조금 더 객체지향적인 프로그래밍을 연습할려면 이런 단계까지 연습을 해야한다.
그래야지 다른 인사이트가 생긴다.
매번 controller, repository 만든다고 실력이 늘지 않는다.
클래스 분리 연습을 위해 활용할 수 있는 원칙
- 일급 콜렉션을 쓴다.
- 3개 이상의 인스턴스 변수를 가진 클래스를 쓰지 않는다.
'정보 > The 공부' 카테고리의 다른 글
스터디하고난후 (0) | 2022.11.17 |
---|---|
도메인 로직은 무엇일까? (0) | 2022.11.11 |
[JS - 심화] TDD란? (0) | 2022.11.06 |
[JS - 심화] Differences whith Throw and Return (0) | 2022.11.05 |
[고찰] 상처 받지 않으면서 피드백 주고 받기 (1) | 2022.11.04 |