
[인터페이스와 enum을 활용한 if문 제거]
- 인터페이스를 찾기 위한 정량적인 원칙 찾기
- if문이 반복된다면 if문을 제거한다.
- 요구사항이 지속적으로 변화 발전하는 데에 적용하면 특히 효과가 좋음
- 다른 부분에 영향을 주지 않으면서 새로운 기능을 추가할 수 있음
- 로직의 복잡도와 중요도가 높은 곳들은 if/else가 많음
- 인터페이스 분리 후 구현체들이 생기는데 이때 구현체들에도 중복코드들이 생긴다면 인터페이스로 해당 코드블럭 옮기는 형식으로 리팩토링
- 인터페이스가 있고 구현체들이 여러개 있을 때 일부만 중복된다고 하면 추상클래스를 사이에 두고 구현하는게 낫다.
- handlerMethodArgumentResolver도 같은 패턴의 인터페이스
[2023개발자에게 가장 필요한 역량]
- 굴러가는 자동차의 바퀴를 갈아끼는 힘!
- 점진적으로 리팩터링하는 전략
- 초반에는 상당히 느리고, 답답하다.
- 점진적 리팩터링의 장점? 비즈니스 요구사항을 수용하면서 리팩터링 가능
- 스트랭글러(교살자)패턴
- as-is와 to-be가 공존하는게 핵심
- 만약 LottoNumber를 만들어 이를 Integer 대체해서 사용하고자 한다면?
- 필드하나 추가
List<LottoNumber> numbers2
- 클래스 하나 추가
LottoNumber2
- 미션 진행할때 컴파일 에러를 발생하지 않고 점진적으로 리팩터링 하는 습관을 들이자.
[웹 레거시코드 리팩터링]
- 웹 어플리케이션 개발에서 tdd 잘 하는 방법? 테스트하기 어려운 코드와 테스트하기 쉬운 코드를 분리한 후 테스트하기 쉬운 코드를 tdd로 구현하는 것을 목표로 한다.
- tdd는 단위테스트에 집중.
- 테스트하기 어려운 부분은 나중에 인수테스트를 통해서 하자.
- 테스트하기 어려운 부분의 의존관계를 한단계 위로 올리자.
- 테스트하기 어려운 코드는 상위인 서비스 레이어에 두고 테스트하기 쉬운 부분을 하위 노드인 도메인으로 이동한다.
- 보통 서비스 레이어에 대한 테스트코드를 작성하지 않지만 레거시코드 리팩터링이기때문에 서비스 레이어도 테스트코드를 작성한다.(모키토)
- 요구사항 분석 후 도메인 객체설계 사이클(객체 설계 -> tdd 구현 -> 도메인 지식 쌓기 -> 코드 구현)
- 기존 코드를 보고 도메인 객체간 의존관계를 살핀다 -> 의존관계가 가장 없는 말단 노드를 찾는다. -> 거기서부터 tdd를 시작한다.(=테스트코드를 작성한다)
- tdd는 bottomUp 방식이 맞다
- out -> in 접근은 도메인 지식이 없거나 요구사항 복잡도가 높은경우 적합
- in -> out 은 그 반대 => 가장 핵심의 도메인(가장 작은 단위의 오브젝트)을 찾기 쉬우니까
- service layer는 thin layer DB 호출, 트랜잭션 처리, 도메인에서의 메서드 호출만을 담당(like controller)
- 도메인 객체의 인스턴스 변수를 줄이기 위해 상속등을 활용하면 좋다.
[메서드 분리]
- OOP Object는 의인화 in 객체지향의 사실과 오해
- CQRS 패턴 => Command와 Query를 분리(=조회와 CUD를 분리) 읽기는 읽기만 변경은 변경만 하도록 하면 메서드 분리를 쉽게 할 수 있다.
- 엘레강트오브젝트에서는 객체에게 메시지를 보내서 상태를 보낼때는 메서드명이 동사여야한다. 그리고 이런 메서드는 반환값이 없다(조정자라고 칭함.) 그러나 반환값이 있는 경우는 명사로 시작하는 것이 맞다고 생각함.
- 이 CQRS 패턴을 적용하면 이 명명규칙을 사용하기 편함.
[엔티티와 도메인]
- 데이터베이스 컬럼과 1:1로 매칭되는 객체(엔티티)
- 엔티티와 도메인객체를 분리하면 중복코드가 발생하기 쉬움.
- 원칙을 지향하는 사람은 엔티티(데이터베이스와 매핑하는 객체)와 도메인 객체를 분리함. 그런데 이거 자체가 복잡도 높일 수 있다.
- 이러한 방식이 복잡도를 높인다고 판단하는 개발자는 엔티티에서 비즈니스로직 구현함. 그러나 이 방식은 테이블에 의존되기땜에 나중에 유지보수 힘들 수 있음.
- 테이블 컬럼 수가 적으면 같이 관리해도 된다. 그러나 중요도와 복잡도가 높으면 분리하는 것도 좋은 방법임.
- 엔티티가 곧 도메인인 개발에서는 클래스 분리를 어떻게 하나요? 분리할 때마다 테이블을 만드는거? 아님. 분리된 클래스를 모조리 다 엔티티로 설정하지는 않음.
- 디비와 도메인이 강결합 된다고 생각하여 분리하는게 맞기도 하지만 실제 이렇게 개발하기 쉽지 않음.
- 웬만한 경우 하나의 객체에서 엔티티 & 도메인 역할을 하는게 상당부분 맞다. 하다가 도저히 안되면 도메인 분리를 하는데, 그 전에 일급컬렉션이나 클래스를 분리하면서 로직 분리를 해보자.
- 테이블 1에 객체 N개가 나오도록 개발해야함. 다수의 객체가 하나의 테이블에 속하게 되도록!
[Wrapping 원칙 팁]
- 무조건 문자열/원시값 래핑하면 오히려 복잡도 증가
- 해당 인스턴스 변수에 관련한 로직이 많은 경우 래핑하는 것이 의미있음.