Ch.12 메소드(함수): 좋은 클래스에는 좋은 메소드가 있다
💡 메소드
- 메소드 설계는 클래스 설계와 아주 밀접한 관련
1. 반드시 현재 클래스의 인스턴스 변수 사용하기
- 인스턴스 변수 안전하게 조작하도록 메소드 설계 → 클래스 내부 정상적 상태 보장 가능
- 반드시 현재 클래스의 인스턴스 변수 사용토록 설계
- 완전 생성자 패턴(가드 in 생성자)
- 값 변경 원하면, 새로운 인스턴스 생성, 리턴 받아 사용
2. 불변 활용해 예상 가능한 메소드 만들기
- 불변 (final) 활용해 예상치 못한 동작 자체를 막을 수 있도록 설계
3. 묻지 말고 명령하기
- 다른 클래스의 상태 확인하고 조작하는 메소드 구조 = 낮은 응집도 구조 = Bad
- getter / setter 는 이런 구조를 만드는 원흉
- 데이터 클래스일 가능성이 높음
- 데이터 클래스를 여러 컨트롤러에서 활용 중에 병행처리한다면 큰 문제
- 낮은 응집도
- 복잡한 처리는 호출 쪽보다 호출당한쪽에서 구현
- 이 때 필요한 게
묻지 말고 명령
- 캡슐화 오해 금지
- 데이터와 데이터 조작 로직을 하나의 클래스로 묶는 것
- 필요한 로직만 외부에 공개하는 것
- 유효성 검사를 통해 부적절한 인스턴스 생성 자체를 금하는 것
4. 커맨드/쿼리 분리
- 메소는 커맨드 / 쿼리 중 하나만 하도록 설계
- 가독성 향상
- 의도치 않은 결과 방지
5. 매개변수
불변 매개변수
- 매개변수에 final 로 불변화
- 매개변수 변경하고 싶으면
- 불변 지역변수 만들어 값을 할당하는 형태로 구현
플래그 매개변수 사용 않기
- 내부 로직 확인 필요 → 가독성 감소
- 전략 패턴으로 해소
null 전달 않기
- NPE 발생 가능성 원천 차단
- null에 의미 부여하지 않기
- Equipment.EMPTY 이런 구현법 기억하기
출력 매개변수 사용 않기
- 매개변수는 입력값으로만 사용해야 함
- 매개변수를 출력에 사용하면 안 됨
매개변수 최대한 적게 사용하기
- 매개변수가 많으면, 별도 클래스로 분리해서 사용하기
- 매개변수에 VO 사용하란 의미
6. 리턴 값
VO 사용해서 리턴 값 의도 나타내기
- 단순한 기본 자료형 사용하면 리턴 값 의미 호출부에 전달 불가
- 독자 자료형 사용해 의도 명확 전달
- 실수하면 컴파일 에러가 발생 → 고치기 쉽다
null 리턴하지 않기
- 받지도 말고, 리턴하지도 말고
- null 이 발생할 상황 자체를 막자
오류는 리턴 값 말고 예외로 처리하기
- 중의적 값 사용하지 않기
- Location(-1, -1) 이런 값은 로직을 위태롭게 함
- 잘못된 상황에서는 예외 발생이 맞다
💡 메소드 이름 설계
- 메소드 구조적 문제는 이름에서 드러남
- 메소드, 클래스 이름이 최대한 동사 하나로 충분하도록 설계
- 부적절한 위치에 있는 boolean 메소드 주의
- 범용 클래스에 boolean 메소드 두지 말란 의미
💡 static 메소드와 관련된 주의 사항
- static 메소드는 같은 클래스에 정의된 인스턴스 변수 조작 불가 → 낮은 응집도 유발
- 응집도 낮아지는 문제 걱정할 필요 없는 경우만 사용