코드 : 기계가 이해하고 실행할 수 있도록 작성된 요구사항의 명세이자 언어이다.
-> 엄밀하고 정확하며 상세해야 함 (단순화만이 답이 아님.)
-> 기능의 의도를 분명히 드러내야 하며, 중복을 피하고 검색하기 쉬워야 함.
깨끗한 코드의 특징
클래스 이름은 명사가 적절 ( User, Order처럼 역할을 표현 )
메서드 이름은 동사나 동사구로 표현하는게 적절함 (get으로 시작하는 메서드, calculateTotal, send~ 등, 이들 처럼 동작을 표현한다.)
일관성을 유지해야함 -> 같은 의미의 개념에는 일관성있게 같은 단어를 사용해야 함.
( 예를들어, fetch, get, retrieve 중 하나만 사용하는것이 좋다.
마찬가지로, 같은 동작을 하는 개념에는 같은 단어를 일관성있게 사용해야한다. (동일 코드 기반에 controller, manager, driver 를 혼재해서 쓴다면 안되겠지?)
인코딩을 피하라 ( 변수나 클래스 이름에 불필요한 정보를 붙이는 것을 의미.)
헝가리식 표기법
변수 이름에 데이터 타입을 붙이는 방식임.
예: strName, iCount
➡️ IDE가 타입을 알려주니 더는 필요하지 않음.
멤버 변수 접두어
변수 이름 앞에 _나 m_을 붙이는 방식임.
예: _userName, m_password
➡️ 읽기 어렵고 비일관적임.
인터페이스와 구현 클래스 구분
인터페이스 이름에 I를 붙이거나, 구현 클래스에 Impl을 붙이는 방식.
좋은 예: UserService, UserServiceDefault
-> 불필요한 정보는 빼고, 이름만으로 의도를 명확히 드러내야 한다.
인터페이스와 구현 클래스 구분 에 관한 의문점: 현재 진행하고 있는 커넥티 개인 프로젝트에서는 하위 구현 클래스 이름으로
UserServiceImpl을 사용하고 있다.
이 부분이 걸리는데, 클린코드의 관점에서는 Impl 같은 이름이 클래스의 역할이나 의도를 명확히 드러내지 못한다고 보는 것으로 보인다.
이것을 클린코드의 관점에서 개선하려면, 역할을 명확히 표현 해야하고, 클래스 이름만 보고도 어떤 구현인지 알 수 있도록 이름을 지어야 하는 것일까? 스프링에서는 Impl을 관용적으로 사용하는 경우가 많은 것으로 알고있다.
의미를 더 드러낼 수 있는 이름으로 리팩토링하면 가독성이 좋아지려나?
-> 지금 사용하는 UserServiceImpl가 스프링 환경에서는 흔히 쓰이는 방식이 아닌가? 개선이 필요한 것인가?
문제 영역/ 해법 영역의 구분
User, Address, Order UserController, OrderRepository, AddressValidator 1. 해법 영역과 문제 영역의 개념 구분 맥락을 명확하게 개선하기
addrFirstName (주소와 관련된 이름임을 명시) FirstName (맥락이 불분명) 불필요한 맥락을 추가하지 않도록 주의하기
AccountAddressStreet Street (이미 Address 객체 안에 포함된 변수라면 충분함)
구현이 하나뿐인 경우
UserService만으로도 충분함.단일 구현체라면:
UserService만 사용하는 것도 괜찮음.여러 구현체가 있을 가능성이 있다면:
UserServiceImpl대신 역할을 명확히 드러내는 이름을 고려.-> impl 자체도 어느 클래스의 구현체인지를 알 수 있는 이름이여서 나쁜이름은 아니나, profile 별로 서비스 구현체가 달라져야한다면 devUserServiceImpl, prodUserServiceImpl 처럼 변경 하여 사용 (단일책임의 원칙?)