Programming/Clean Code 9

테스트 코드가 실제 코드에 영향을 줘선 안되는가 ?

많은 분들이 테스트 코드가 프로덕트 코드에 영향을 줘선 안된다고 알고 있을 것이다. 나 조차도 내가 개발한 코드는 절대 테스트 코드가 프로덕트 코드에 영향을 주지 않고 있다고 믿었다. 그러던 어느날, 회사 팀 동료 A가 나에게 이런 질문을 했다. 동료 A: Jerry! 서비스 테스트 코드를 작성할 떄 RequestDto가 필요한데, 해당 Dto는 getter만 열어뒀거든요. 서비스 테스트하려면 Builder나 Constructor를 만들어줘야 하나요?? Jerry(본인): (3분 정도 고민하다가..) 헐헐 그러네요!! 저는 테스트가 프로덕트 코드에 영향이 절대 없게 개발하는 것을 목표로 했었는데, 따지고 보면 생성자 조차도 필요 없는 것이네요..! 해당 질문으로 나는 완전 충격을 받았다. 상황 상황은 이..

Clean Code - 소프트웨어 창발성(Emergence)

창발성(Emergence) 창발 현상이란 단순한 결합이 의도와 관계 없이 어떠한 결과를 나타나는 현상을 의미한다. 가령, 붉은악마 신드롬은 정부나 월드컵조직위원회가 특정한 계획에 따라 조직한 것이 아니라, 국민들이 인터넷과 방송매체, 주변과의 접촉 등을 통해 자발적으로 상호작용을 일으키며 나타난 현상이다. 아래 켄트 벡이 제시하는 단순한 설계 규칙 네 가지를 따르면 소프트웨어 설계 품질을 크게 높여주는 결과가 발생한다고 믿는다. 모든 테스트를 실행한다. 중복을 없앤다. 프로그래머 의도를 표현한다. 클래스와 메서드 수를 최소로 줄인다. 위 목록은 중요도 순이다. 모든 테스트를 실행하라. 모든 설계는 의도한 대로 돌아가는 시스템을 내놓아야 한다. 문서로는 시스템을 완벽하게 설계했지만, 시스템이 의도한 대로 ..

Clean Code - 깨끗한 시스템이란 무엇인가?! (+ 관심사 분리)

깨끗한 시스템 시스템을 도시에 비유해보자. 도시의 온갖 세세한 사항을 혼자서 관리할 수 있을까? 그럴 순 없다. 그럼에도 도시는 잘 돌아간다. 수도관리 팀, 전력관리 팀, 교통관리 팀, 치안관리 팀 등 각 분야를 관리하는 팀이 있기 때문이다. 누군가는 각 팀의 역할을 자세히는 몰라도 대략적으로 파악하고 전체 그림을 설계하기도 한다. 누군가는 자신의 팀의 역할과 관련 팀과의 이해 관계 정도 까지만 집중한다. 이러한 부분이 프로그래밍에서는 적절한 추상화와 모듈화이다. 팀이 제작하는 시스템도 객체들을 적절하게 관심사를 분리해서 추상화를 이뤄내게 된다. 시스템 수준에서도 깨끗함을 유지하는 방법에 대해서 알아보자. 시스템 제작과 사용을 분리하라 제작(Construction)과 사용(Use)는 많이 다르다. 소프트..

Clean Code - 깨끗한 클래스란 무엇인가?! (클래스 고찰)

깨끗한 클래스 해당 포스팅은 클래스에 대해 다룬다. 깨끗한 클래스란 무엇인가에 대해 알아보자. 클래스 체계 깨끗한 클래스를 정의할 때 따르는 표준 자바 관례가 있다. 클래스의 내부 요소를 정의할 때 가장 먼저 변수 목록을 정의한다. 변수 중에서는 가장 먼저 static public 상수를 정의하고 다음으로 static private 변수를 정의한다. 그 다음 private 인스턴스 변수를 정의한다. 변수 목록 다음에 public 메소드를 정의하고 그 다음 private 메소드를 정의한다. 클래스가 내부에서 추상화 단계가 순차적으로 내려가는 관례를 지키면서 신문 기사처럼 읽히는 효과를 가진다. 캡슐화 변수와 유틸리티 함수는 가능한 공개하지 않는 것이 좋지만 반드시 숨겨야 한다는 법칙도 없다. 내가 속한 팀..

Clean Code - 깨끗한 테스트 코드 유지하기

개요. 애자일과 TDD 덕택에 단위 테스트를 자동화하는 개발자들이 이미 많아졌고 점점 더 늘어나는 추세다. 하지만 많은 개발자들이 테스트 코드 작성을 급하게 서두르면서 제대로 된 테스트 케이스 작성을 놓치고 있다. 제대로 된 좋은 테스트 케이스를 작성하는 것에 대해 알아보자 TDD 법칙 세 가지 지금은 TDD가 실제 코드를 짜기 전에 단위 테스트부터 작성하라고 요구한다. 아래는 TDD가 추구하는 세 가지 원칙이다. 실패하는 단위 테스트 를 작성할 때까지 실제 코드를 작성하지 않는다. 컴파일은 실패하지 않으면서 실행이 실패하는 정도로만 단위 테스트를 작성한다. 현재 실패하는 테스트를 통과할 정도로만 실제 코드를 작성한다. 위 세가지 규칙을 지키면 개발과 테스트가 대략 30초 주기로 묶인다. 추가적으로 테스..

Clean Code - 외부 코드 사용하기 (+ 경계 클래스, 어댑터 패턴)

개요. 시스템에 들어가는 모든 소프트웨어를 직접 개발하는 경우는 드물다. 패키지를 사거나 라이브러리 등 오픈 소스를 사용하기도 한다. 이 때 우리는 외부 코드를 우리코드에 어떻게 해야 더 깔끔하고 안전하게 통합할 수 있는 지 고민해야 한다. 고민은 외부 코드와 우리 코드의 경계를 파악하는 것부터 시작한다. 경계(Boundaries) 전체 소프트웨어 개발에 사용하게 되는 외부 코드를 내 코드에서 호출하는 부분을 경계(boundaries)라고 한다. 경계 없이 단순하게 외부 코드를 사용하려는 곳에서 직접 호출할 수 있지만 그렇게 했을 때 아래와 같은 문제가 생긴다. 인터페이스 제공자가 지원한 인터페이스를 그대로 사용해야 한다. 인터페이스 제공자는 최대한 범용적이게 개발하는 것을 선호한다. 인터페이스 사용자는..

Controller, Service, Repository를 Static으로 하지 않는 이유!!

Static class ? 어제 레거시 프로젝트를 받아서 기능 개선을 진행하게 되었습니다. 코드가 조금 신기했던게, Controller, Service, Repository가 정적 클래스(class)로 되어 있었습니다. Controller에서 Service의 메소드를 호출할 때 Service.method() 형식으로 호출하고 인스턴스를 생성하지 않는 방법입니다. Why? 정적 클래스(Static class)로 사용하면 어차피 재사용하게되고, 큰 문제는 없지 않나? 싶었습니다. 실제로 99%의 MVC 메서드는 정적으로 사용할 수 있다고 합니다. 그렇다면 왜 정적 클래스를 사용하지 않고, 싱글톤(Singleton)으로 instance를 만들어서 사용할까요? DI(의존성 주입) 정적 클래스는 상태를 가지지 않..

Clean Code - 예외 처리 시 놓치는 부분 정리 (Log, Null 검사, Checked exception)

반드시 Log를 남겨라 예외가 발생하면 대부분 언어에서는 호출 스택을 남깁니다. 하지만, 호출 스택만으로 왜 예외가 발생했는지를 알려면 많은 노력이 필요합니다. 따라서 반드시 catch문에서 충분한 로그를 남기는 것이 좋습니다. public void sendShutDown() { try { tryToShutDown(); } catch (DeviceShutDownError e) { logger.log(e); } } null을 반환하지 마라 아래의 코드를 보면 뭔가를 get 할때마다 null이 아닌지 검사를 하고 있습니다. 이렇게 코드를 구현한다면 프로젝트 하나에 거의 모든 곳에 null 검사가 들어가야 합니다. 누락되서 말썽을 일으키기도 쉽고, 코드도 더러워집니다. public String getCompa..

Clean Code - 부울(Boolean) 매개변수는 절대 피하라!

부울 매개변수를 사용하는 경우 클린 코드를 읽다가 부울 인수를 절대로 사용하지 말라는 강력한 주장을 보게 되었습니다. 부끄럽게도 전날 프로젝트를 개발하면서 함수 인수로 boolean을 사용하게 수정했는데 말이죠..ㅎㅎ.. 함수의 인수로 부울(Boolean)을 사용하게 되면 해당 인수가 참인지 거짓인지에 따라서 다른 동작을 한다는 말이 되는데, 그러면 가독성도 나쁘고, 책임도 모호해집니다! 그래서 두개의 함수로 분리하는 것이 좋은 것 같습니다. 적용 방안 제가 작성한 기존의 코드는 아래와 같습니다. (설명을 위해 조금 수정했습니다.) 관리자 API Controller findAllWithNotActivated = async ( req: Request, res: Response ) => { const res..