Skip to content

[✨feat] ScrapCount VO 구현 #47

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 21 commits into from
May 26, 2025
Merged

[✨feat] ScrapCount VO 구현 #47

merged 21 commits into from
May 26, 2025

Conversation

jsoonworld
Copy link
Member

📄 Work Description

InternshipAnnouncement의 스크랩 수를 관리하기 위한 값 객체 ScrapCount를 구현했습니다.
정수 기반의 단순 필드를 VO로 추출하여 불변성과 도메인 책임을 명확히 했습니다.

  • from()을 통해 항상 0으로 초기화되며 외부 값 주입은 허용하지 않습니다.
  • increase()decrease()를 통해 상태를 변경하며, 감소 시 0 이하로 내려갈 수 없도록 보호합니다.
  • equals, hashCode, toString을 오버라이딩하여 VO 특성을 갖추었습니다.

💭 Thoughts

  • 조회수와 달리 스크랩 수는 증가와 감소가 모두 필요한 값이므로 decrease() 메서드를 추가했습니다.
  • 음수로 감소하지 않도록 방어 로직을 포함하여 도메인 무결성을 보장합니다.
  • 이후 InternshipAnnouncement 엔티티에 적용하여 책임 분리 및 테스트 가능성을 높일 예정입니다.

✅ Testing Result

스크린샷 2025-05-18 오후 3 19 53


🗂 Related Issue

- 스크랩 수를 책임지는 값 객체 ScrapCount를 구현했습니다.
- 외부에서 임의의 값을 주입할 수 없도록 생성자를 제한하고, 항상 0에서 시작하도록 from() 메서드를 제공합니다.
- increase(), decrease()를 통해 상태를 변경하며, 값은 0 미만으로 감소할 수 없도록 예외 처리를 포함했습니다.
- equals, hashCode, toString을 오버라이딩하여 값 객체로서의 동등성 비교를 보장합니다.
- from() 호출 시 0으로 초기화되는 ScrapCount의 생성 동작을 검증했습니다.
- increase()와 decrease()를 통해 각각 값이 1씩 증가/감소하는 동작을 확인했습니다.
- 값이 0일 때 decrease()를 호출하면 예외가 발생하는 케이스도 검증했습니다.
Copy link

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

Implements a value object to manage scrap counts on InternshipAnnouncement, enforcing immutability and non-negative constraints, with unit tests.

  • Add ScrapCount VO with increase(), decrease(), validation, and JPA embedding
  • Cover initial value, increment/decrement behavior, and underflow exception in tests

Reviewed Changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.

File Description
src/main/kotlin/com/terning/server/kotlin/domain/internshipAnnouncement/ScrapCount.kt Implemented ScrapCount VO with validation and JPA annotation
src/test/kotlin/com/terning/server/kotlin/domain/internshipAnnouncement/ScrapCountTest.kt Added tests for initial, increase, decrease, and underflow
Comments suppressed due to low confidence (1)

src/test/kotlin/com/terning/server/kotlin/domain/internshipAnnouncement/ScrapCountTest.kt:1

  • There are no tests for equals(), hashCode() or toString(). Adding these would ensure full VO behavior coverage.
package com.terning.server.kotlin.domain.internshipAnnouncement

@Embeddable
class ScrapCount private constructor(
val value: Int,
) {
Copy link
Preview

Copilot AI May 18, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

JPA @embeddable classes require a no-argument constructor (at least protected) for runtime instantiation. Consider adding a protected default constructor alongside the private one.

Suggested change
) {
) {
protected constructor() : this(MIN_VALUE)

Copilot uses AI. Check for mistakes.

Copy link
Member Author

@jsoonworld jsoonworld May 26, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

아하! 제안해주신 내용 확인했습니다 🙇‍♀️
JPA에서 @Embeddable 클래스는 런타임에 인스턴스를 생성할 수 있도록
protected 기본 생성자가 꼭 필요하다는 점을 깜빡했던 것 같아요!

말씀해주신 대로 protected 생성자를 추가해서 JPA에서도 문제없이 동작하도록 개선해보겠습니다 :)

import jakarta.persistence.Embeddable

@Embeddable
class ScrapCount private constructor(
Copy link
Preview

Copilot AI May 18, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nitpick] Consider making this a Kotlin data class to auto-generate equals, hashCode, and toString, reducing boilerplate.

Suggested change
class ScrapCount private constructor(
data class ScrapCount private constructor(

Copilot uses AI. Check for mistakes.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이 부분은 이전 피드백에서도 언급되었던 것 같은데요!

data class로 변경하면 equals, hashCode, toString 같은 보일러플레이트를 줄일 수 있다는 점에서 확실히 매력적인 선택인 것 같아요.

다만 도메인 모델을 data class로 사용할지에 대한 부분은 조금 더 팀원들과 방향을 정리한 뒤 적용하는 게 좋을 것 같아서, 관련 이슈로 등록해두고 함께 논의해보겠습니다!

피드백 감사합니다 🙏

package com.terning.server.kotlin.domain.internshipAnnouncement

import jakarta.persistence.Embeddable

Copy link
Preview

Copilot AI May 18, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nitpick] Add KDoc above the class to explain the domain intent, invariants (non-negative), and usage examples for future maintainers.

Suggested change
/**
* Represents the count of "scraps" in the domain model.
*
* This class enforces the invariant that the count must always be non-negative.
* It provides methods to increase or decrease the count, ensuring that the value
* never drops below zero.
*
* Example usage:
* ```
* val initialCount = ScrapCount.from() // Creates a ScrapCount with value 0
* val increasedCount = initialCount.increase() // Increases the count to 1
* val decreasedCount = increasedCount.decrease() // Decreases the count back to 0
* ```
*/

Copilot uses AI. Check for mistakes.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이 부분은 클래스와 메서드, 변수명에서 의도가 꽤 명확히 드러나고 있어서
별도의 KDoc 없이도 충분히 전달될 수 있을 것 같다고 생각했어요!
그럼에도 불구하고 유지보수 관점에서 의미 있는 제안이라는 점에 공감합니다 🙏

앞으로 설명이 부족한 클래스가 생긴다면 이번 제안처럼 KDoc도 함께 고려해보겠습니다.
좋은 제안 감사합니다!

Copy link
Member

@leeeyubin leeeyubin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

스크랩 수를 위한 증가, 감소 함수 잘 보았습니다! 수고하셨어요~

@pull-request-size pull-request-size bot added size/L and removed size/M labels May 26, 2025
@jsoonworld jsoonworld changed the base branch from feat/#44 to develop May 26, 2025 11:55
@jsoonworld jsoonworld added size/M and removed size/L labels May 26, 2025
@jsoonworld jsoonworld merged commit 0ee63d3 into develop May 26, 2025
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[✨feat] ScrapCount VO 구현
2 participants