Commit bae2e6a
authored
1단계 - 레거시 코드 리팩터링 (#801)
* feat: 개발 환경 자동화 및 코드 포맷터(Spotless) 적용
.gitignore
- diff 디렉토리 무시 규칙 추가
.sdkmanrc
- Java 버전 설정 파일 추가 (11.0.21-tem)
Makefile
- diff 생성/정리, validation, init 등 스크립트 실행 타겟 추가
build.gradle
- Spotless 플러그인 추가
- Java 포맷팅 규칙(palantir format 등) 설정 적용
clean-diff.sh
- diff/commit 디렉토리 내 패치 파일 정리 로직 추가
commit-diff.sh
- 스테이지된 변경사항을 timestamp 포함 패치 파일로 저장 기능 추가
origin-ghtjr410-diff.sh
- origin/ghtjr410 대비 현재 브랜치 diff 생성 스크립트 추가
pre-commit
- Java 변경 시 Spotless 검사 자동 수행 훅 추가
init.sh
- Git hook 설정 및 스크립트 실행 권한 부여 자동화
validate.sh
- Spotless 적용/검사 및 프로젝트 빌드를 자동 수행하는 검증 스크립트 추가
* docs: README 수정 및 1단계 리팩터링 문서/체크리스트 추가
README.md
- 프로젝트 제목 수정 및 LMS/TDD 소개 추가
- 단계별 문서 링크(1~4단계) 추가
01-legacy-code-refactoring.md
- 1단계 리팩터링 학습 목표, 요구사항, 힌트, PR 체크 항목 문서화
checklist.md
- 미션 제출 전 객체지향 원칙, TDD 원칙, 테스트 품질 등 체크리스트 추가
* style: Spotless 코드 포맷팅 적용
* refactor: Answer 삭제 로직을 도메인 메서드로 캡슐화하고 테스트 추가
Answer.java
- setDeleted(boolean) 메서드 제거
- delete(LocalDateTime) 도메인 메서드 추가하여 삭제 처리 및 DeleteHistory 생성 일원화
- delete 호출 시 deleted 플래그 true 설정
QnAService.java
- Answer 삭제 시 setDeleted + DeleteHistory 생성 로직을 answer.delete(now) 호출로 단순화
AnswerTest.java
- delete 메서드 동작 검증 테스트 추가
- 삭제 후 DeleteHistory 반환 및 deleted 플래그 true 검증
* refactor: Question 삭제 로직 도메인으로 이동 및 권한 검증 테스트 추가
Question.java
- isOwner 메서드를 private으로 변경하여 외부 직접 호출 차단
- setDeleted(boolean) 제거
- delete(loginUser, now) 메서드 추가하여 권한 검증 및 DeleteHistory 생성 일원화
- 삭제 권한 없을 경우 CannotDeleteException 발생 처리 추가
QnAService.java
- 서비스 레이어에서의 직접 권한 검사 및 삭제 처리 로직 제거
- question.delete(...) 호출로 삭제 처리 단일화
QuestionTest.java
- 질문 삭제 성공 테스트 추가
- 소유자 불일치 시 CannotDeleteException 발생 테스트 추가
* refactor: 질문·답변 삭제 로직을 Question 도메인으로 완전 통합하고 검증 강화
Question.java
- getAnswers 제거하여 외부 접근 최소화
- delete 메서드를 Question 내부에서 답변까지 함께 삭제하도록 변경
- validateDeletable 추가: 질문 소유자 검증, 타인 답변 존재 시 예외 처리
- delete 시 질문/답변 DeleteHistory 목록 생성 후 반환
QnAService.java
- 서비스 레이어 삭제 검증 및 반복 로직 제거
- question.delete(...) 호출만으로 삭제 처리 일원화
QuestionTest.java
- 삭제 성공 테스트 수정: 답변 존재 시 DeleteHistory 리스트 검증
- 소유자 불일치 예외 검증 추가
- 타인 답변 존재 시 CannotDeleteException 발생 테스트 추가
* refactor: 중복 삭제 메서드 및 불필요한 접근자 정리
Answer.java
- delete(LocalDateTime) 메서드를 클래스 상단으로 이동하고 중복 정의 제거
- 불필요한 getContents() 제거
Question.java
- delete 메서드 및 validateDeletable 메서드를 상단으로 재배치하고 중복 블록 제거
- title/contents setter 제거로 불변성 강화
- 전체 구조 정리하여 중복 코드 제거 및 가독성 향상
* refactor: Answer 목록 전용 값 객체 Answers 추가 및 삭제/검증 로직 위임
Answers.java
- Answer 리스트를 캡슐화하는 값 객체 추가
- deleteAll(now): 모든 Answer 삭제 수행 후 DeleteHistory 리스트 반환
- validateDeletable(loginUser): 삭제 가능 여부 검증(타인 답변 존재 시 예외 발생)
AnswersTest.java
- 소유자 일치 시 예외 없이 통과하는 검증 테스트 추가
- 소유자 불일치 시 CannotDeleteException 발생 테스트 추가
* refactor: Question이 Answer 컬렉션을 Answers 값 객체로 위임하도록 구조 개선
Answers.java
- add 메서드 추가로 Answer 등록 책임 부여
- deleteAll(now) 기존 로직 유지
- validateDeletable(loginUser) 그대로 활용
Question.java
- answers 필드를 List → Answers 로 교체하여 컬렉션 캡슐화
- 삭제 시 answers.deleteAll(now) 사용으로 책임 위임
- 검증 로직도 answers.validateDeletable(loginUser) 호출로 단순화
* refactor: 공통 엔티티 속성을 BaseEntity로 분리하고 Answer·Question에 상속 적용
Answer.java
- BaseEntity 상속 적용으로 id/createdDate/updatedDate 필드 제거
- 생성자에서 super(id) 호출로 id 설정 위임
- delete 시 getId() 사용하도록 변경
- 중복 필드 제거로 엔티티 구조 단순화
BaseEntity.java
- id, createdDate, updatedDate 공통 필드 추가
- getId() 제공
- Answer/Question의 공통 속성을 추출한 추상 엔티티 생성
Question.java
- BaseEntity 상속 적용 및 id 관련 필드 제거
- 생성자에서 super(id) 호출하도록 변경
- DeleteHistory 생성 시 getId() 사용하도록 수정
* refactor: Question의 title/contents를 전용 값 객체로 분리하여 응집도 향상
Question.java
- title, contents 필드를 제거하고 QuestionContent 값 객체로 대체
- 생성자에서 QuestionContent 생성하여 content 필드에 저장
- toString 수정: content 정보 출력하도록 변경
- 전체 구조를 값 객체 기반으로 단순화
QuestionContent.java
- title, contents를 보관하는 값 객체 추가
- toString 재정의하여 도메인 표현 명확화
* test: Question 삭제 테스트 간소화 및 불필요한 테스트 제거
QuestionTest.java
- 삭제 성공 테스트 수정: 반환된 DeleteHistory 리스트 크기 검증 후 QUESTION 기록 포함 여부만 확인하도록 단순화
- 삭제 여부(isDeleted) 검사 유지
- 중복되는 ‘다른 사람 답변 예외’ 테스트 제거(AnswersTest로 책임 분리됨)
* refactor: 연관관계 설정 위치 정리 및 QuestionContent 접근자 추가
Answer.java
- toQuestion 위치 조정 및 중복 메서드 제거
- 불필요한 코드 정리로 클래스 구조 단순화
Question.java
- addAnswer에서 Answer ↔ Question 연관관계 설정(toQuestion) 명확히 수행
- getWriter 위치 조정 및 중복 제거
- 전체 구조 정돈
QuestionContent.java
- title, contents 조회용 getter 추가
- 값 객체로서 외부 접근이 필요한 영역을 최소한으로 허용
* feat: Answer 삭제 이력 생성 기능 분리 추가
Answer.java
- deleteHistory(LocalDateTime) 메서드 추가하여 삭제 여부 변경 없이 DeleteHistory만 생성하도록 분리
AnswerTest.java
- deleteHistory 동작 검증 테스트 추가
- 특정 시각을 지정해 DeleteHistory 생성 값 검증
* feat: 삭제 이력 생성 기능을 엔티티/컬렉션에서 분리 제공하도록 확장
Answers.java
- deleteHistories(deletedAt) 추가: 삭제 플래그 변경 없이 Answer들의 DeleteHistory만 생성
- 책임 분리로 deleteAll vs deleteHistories 용도 명확화
Question.java
- deleteHistories(deletedAt) 추가: Question + Answers의 DeleteHistory 목록 생성 전용 메서드 제공
- 삭제 여부 변경 없이 이력 생성만 수행
QuestionTest.java
- deleteHistories 테스트 추가
- Question 및 Answer의 DeleteHistory 생성 여부 검증
* refactor: 삭제 행위와 삭제 이력 생성을 완전히 분리하여 도메인 책임 명확화
Answer.java
- delete(LocalDateTime) → delete()로 변경하여 삭제 상태만 변경
- 삭제 이력 생성을 담당하는 deleteHistory(LocalDateTime) 분리
- 내부 delete 로직 단순화 및 책임 분리
Answers.java
- deleteAll(now) 제거 → deleteAll()로 변경하여 상태 변경만 수행
- 삭제 이력 생성 기능은 deleteHistories(LocalDateTime)로 분리하여 순수 히스토리 생성 책임만 담당
Question.java
- delete(loginUser, now) → delete(loginUser)로 변경해 삭제 시각 의존 제거
- 내부적으로 Answer 삭제는 answers.deleteAll() 호출로 단순화
- 삭제 이력 생성은 deleteHistories(LocalDateTime)에서 전담
QnAService.java
- 도메인 delete 호출 후 별도로 deleteHistories(now) 호출하여 이력 생성
- 삭제와 삭제 이력 저장을 명확히 분리
AnswerTest.java
- delete()는 상태 변경만 검증하도록 테스트 단순화
QuestionTest.java
- delete() 결과로 DeleteHistory가 반환되지 않으므로 관련 검증 제거
- 삭제 여부 검증만 유지
- 소유자 불일치 테스트는 delete(loginUser)로 수정
* refactor: 삭제 시각을 고정하여 일관된 DeleteHistory 생성
QnAService.java
- LocalDateTime.now()를 한 번만 호출해 fixedNow로 저장
- question.delete(loginUser) 이후 deleteHistories 생성 시 fixedNow를 재사용하여 삭제 이력 시간 불일치 문제 해결
* docs: 리팩터링 PR 링크 및 구현 기능 목록 문서에 추가
01-legacy-code-refactoring.md
- PR 링크 추가
- 구현 기능 목록 상세 추가(도메인 리팩터링·서비스 로직·테스트 항목 정리)
- 전체 리팩터링 진행 내역을 문서로 구조화하여 가독성 향상
* refactor: 엔티티 공통 삭제 기능을 DeletableBaseEntity로 통합하고 Answer/Question 구조 개선
Answer.java
- BaseEntity → DeletableBaseEntity 상속으로 변경
- deleted 필드 제거 (부모로 이동)
- delete() 제거 및 상위 protected delete() 활용
- deleteHistory 메서드는 그대로 유지
- toString 개선 및 중복 코드 정리
BaseEntity.java
- 기존 BaseEntity 삭제 (DeletableBaseEntity로 통합)
DeletableBaseEntity.java
- id, createdDate, updatedDate, deleted 공통 관리
- delete(), isDeleted() 제공
- 엔티티 공통 toString 구현
Question.java
- BaseEntity → DeletableBaseEntity 상속 변경
- deleted 필드 제거 (부모 클래스에서 관리)
- delete() 내부에서 상위 delete() 호출
- isDeleted() 제거 (상위 클래스 제공)
- toString 개선 및 구조 단순화
* feat: Answer 삭제 시 소유자 검증 로직 추가 및 테스트 보강
Answer.java
- delete(NsUser) 추가: 삭제 전 소유자 검증 수행
- 소유자 불일치 시 CannotDeleteException 발생
- 기존 delete() 로직을 상위 delete() 호출로 위임
AnswerTest.java
- delete_소유자일치_성공 테스트 추가
- delete_소유자불일치_예외발생 테스트 추가
- 삭제 이력 생성 테스트(deleteHistory)는 그대로 유지
* refactor: Answer 개별 삭제 책임 이전으로 Answers의 삭제 검증 제거 및 관련 테스트 삭제
Answers.java
- validateDeletable 제거
→ 소유자 검증 책임을 Answer.delete(loginUser)로 완전히 이관
- Answers는 컬렉션 관리와 일괄 삭제(deleteAll)·이력 생성(deleteHistories)만 담당
Question.java
- validateDeletable 삭제에 따라 내부 검증 로직 단순화
→ 질문 소유자 검증만 수행
→ 답변 삭제는 answers.deleteAll()이 Answer.delete()를 호출하며 처리
AnswersTest.java
- validateDeletable 제거에 따라 해당 테스트 클래스 전체 삭제
* refactor: 삭제 권한 검증을 Answer로 위임하고 출력 포맷 및 일괄 삭제 로직 개선
Answer.java
- toString에서 question 정보 제거하여 간결화
Answers.java
- deleteAll(loginUser)로 변경하여 각 Answer가 소유자 검증을 수행하도록 위임
- Answer.delete(loginUser) 호출 구조로 일관성 확보
DeletableBaseEntity.java
- toString 포맷 수정(불필요한 '}' 제거)
Question.java
- delete 수행 시 answers.deleteAll(loginUser) 호출로 삭제 권한 검증 일관화
* test: Question 삭제 테스트 이름을 의도에 맞게 명확화
QuestionTest.java
- `delete_성공` → `delete_소유자일치_성공` 으로 테스트명 변경하여 검증 목적을 더 분명하게 표현
* refactor: 삭제 도메인 로직 및 테스트 명세 정리
01-legacy-code-refactoring.md
- Answer: 삭제 시 소유자 검증 및 상태 변경 단계 명시
- Answers: 불필요해진 삭제 가능 여부 검증 항목 제거
- Question: 삭제 처리 흐름을 단순화(답변 삭제 포함)
- DeletableBaseEntity: 공통 삭제 필드 및 delete() 기능 명세 추가
- 테스트: 메서드명과 시나리오를 명확하게 정리(성공/실패 구분)1 parent de587b9 commit bae2e6a
File tree
41 files changed
+539
-201
lines changed- docs
- scripts
- git/diff
- setup
- git-hooks
- validation
- src
- main/java/nextstep
- courses
- domain
- infrastructure
- payments/domain
- qna
- domain
- infrastructure
- service
- users
- domain
- infrastructure
- test/java/nextstep
- courses/infrastructure
- qna
- domain
- service
- users/infrastructure
Some content is hidden
Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
41 files changed
+539
-201
lines changed| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
31 | 31 | | |
32 | 32 | | |
33 | 33 | | |
| 34 | + | |
| 35 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | | - | |
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
2 | 9 | | |
3 | 10 | | |
4 | 11 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
2 | 2 | | |
3 | 3 | | |
4 | 4 | | |
| 5 | + | |
5 | 6 | | |
6 | 7 | | |
7 | 8 | | |
| |||
12 | 13 | | |
13 | 14 | | |
14 | 15 | | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
15 | 26 | | |
16 | 27 | | |
17 | 28 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
0 commit comments