들어가며안녕하세요, 미래사업부문의 오지산이라고 합니다. 0의 지식으로 부딪혀야
하는 상황이었는데요. 그 과정에서 많이 배우고 의지했던(?) 책이 <클린 코드>였는데요. 신입 개발자에게는 코드를 작성하면서 어떤 가치를 지향해야 하는지가 불명확하게 느껴집니다. 어떤 코드를 깨끗하다고 말할 수 있죠?책에서는 이름, 함수, 클래스, 오류 처리, 동시성 등 다양한 관점에서 이를 논하고 있어서 (또한 책의 내용을 직접적으로 언급하는 경우, 쪽번호를 적어 두었으니 참고하시면 좋을 것 같습니다.) 시작은 테스트부터종종 테스트를 염두에 두면 코드가 깨끗해지기 쉽다는 것을 느낍니다. 혹시 테스트 코드를 짜면서 예상보다 훨씬 복잡해지고 있다는 느낌을 받으신 적 있나요?
이 코드는 제가 첫 개발 미션에서 Spock을 이용해 작성한 테스트인데요. 또한 ByteArrayInputStream을 S3ObjectInputStream 생성자에 끼워 넣고, 테스트 코드의 구성 자체가, 해당 함수가 여러가지 일을 하고 있다는 강한 느낌을 줍니다.
역시 이 함수가 많은 일을 한꺼번에 하고 있다는 것을 알 수 있습니다.
4가지 일에 대한 사전 작업을 해야 했기 때문에, 테스트 코드가 복잡해질 수밖에 없었던 것 같네요. 하나의 함수가 하나의 일을 하게<클린 코드>에서는 좋은 함수의 조건 중 하나로 한 가지 일을 잘 하는 것을 제시합니다. (p.44)
전보다 <클린 코드>에서는 이와 같은 코드 형식을 신문 기사에 비유하고 있습니다. (p.98) 하나의 클래스가 한 가지 책임을 갖게함수를 분리했다고 해도
아직 테스트 코드에 손을 댈 수는 없습니다.
애초에 제가 S3StorageService를 만든 이유는 AWS와 통신하여 S3 버킷에 저장된 객체를 가져오기 위함이었습니다. 이때 재밌는 것은, 함수를 나눴더니 1번과 4번이 겉도는 느낌이 든다는 것입니다.
다른 함수가 인스턴스 변수인 amazonS3와 bucketName을 모두 사용하고 있는 반면, 즉 두 메서드로 인해 클래스의 응집도가 낮아진다는 것을 알 수 있습니다. (p.177) 그러고 보니 AWS와 통신하는 클래스에 key를 만드는 로직이나, 먼저
S3KeyResolver를 만들어 KeyResolver를 구현합니다.
그리고 S3StorageService가 KeyResolver에 의존하게 해 보았습니다.
그 결과 테스트 코드에서도
그래도 아직 테스트 코드는 복잡한데요.
S3Resource는 S3Object에서 InputStream을 꺼내와서, Resource에 담아 돌려주는 책임만 맡습니다.
생각해 보니 두 개로 나눌 수 있는 테스트를 하나의 함수 안에서 진행했다면, <클린 코드>에서는 단위 테스트를 작성할 때 활용할 수 있는 지침을 여럿 제시하고 있는데요.
좀 전의 테스트 함수를 규칙에 부합하는 방향으로 개선하면서, 원래 테스트는 반쪽이 되었고요. 🙂
또한 응집도를 유지하면서 큰 함수를 쪼개다 보니, 작은 클래스 여러 개를 만들 수 있었습니다.
이렇듯 클래스가 하나의 책임을 가지면 개별 테스트를 만들기도 쉬워지고, 가령 key를 만들기 위해 암호화를 적용해야 한다는 요구사항이 주어지면, 반면 지금의 코드에서는 KeyResolver를 구현하는 새 클래스를 만들어 S3StorageService와 결합시키면 됩니다. 경계 분리하기이번에는 조금 더 복잡한 코드를 가져와 보았습니다.
우선 TwitterKoreanProcessorJava 없이 이 상태로 테스트를 만드려면, twitter-korean-text가 정확하게 토큰화할 수 있는 문장을
준비해줘야 합니다. 그리고 혹시, 조금 전 코드에서 Seq를 보셨나요?
Seq는 Scala 표준 라이브러리의 일부입니다. Scala의 Seq 인터페이스가 변경된다고 해서 우리 코드가 영향을 받기를 원하는 사람은 없겠죠. 이처럼 외부 라이브러리를 사용할 때는 경계 인터페이스를 노출하지 않는 것이 좋습니다. (p.146) 다행히 위의 코드는 초안이었고, 몇 번의 수정을 거쳐 아래와 같은 코드로 바꿀 수 있었는데요.
그리고 해당 Tokenizer 인터페이스를 구현한 TwitterKoreanTokenizer를 만들었습니다.
만약 MorphemeAnalyzer의 단위 테스트가 필요하다면
마무리하며저는 이 책을 몇 번에 걸쳐서 나눠 읽으면서 팀 내에서 리뷰를 받았었습니다. 리뷰 때마다 "동료 개발자들에게는 당연한 얘기를 길게 늘어놓는 게 아닌가?"라는 고민을 자주
했었습니다.
라고 해주신 팀원분이 있었기 때문입니다. 팀 내 리뷰에서 들었던 피드백인데요. 가령 테스트만 해도 모두가 짜야 한다고 생각하지만, 코드를 보다 보면 여러 이유로
이 말을 빌려, 지속적인 환기 또한 전문가 집단 사이에서의 중요한 가치가 아닐까 생각해 봅니다. |