Skip to content
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

feat: 인기 게시글 기능 구현 완료 #610

Open
wants to merge 16 commits into
base: develop
Choose a base branch
from
Open

Conversation

SongJaeHoonn
Copy link
Contributor

@SongJaeHoonn SongJaeHoonn commented Nov 8, 2024

Summary

#607

게시판 상단에 핫 게시글을 노출하는 기능을 위해, 지난주의 인기 게시글을 조회하는 api를 구현했습니다.

Tasks

  • hot 게시글 조회 로직 구현

ETC

  • 추후 핫 게시글 개수의 유연한 변경을 위해 파라미터에 size를 추가해 개수 조절이 가능하도록 구현했습니다. (기본값은 5)
  • 만약 인기 게시글의 반응 수가 같다면 최신순으로 정렬합니다.
  • 지난 주의 핫 게시글이 size개보다 적다면, 이번 주를 기준으로 두 주 전, 세 주 전... 을 계속 조회하여 핫 게시글이 size 개수가 될 때까지 반복합니다.
  • 만약 전체 게시글의 개수가 size개보다 적다면 전체 게시글을 반응 순으로 정렬 후 반환합니다.

API Response

  • 2024-11-08일에 api 호출했을 때 (size = 3)

1번 게시글 댓글 1, 이모지 2
2번 게시글 댓글 1, 이모지 5
3번 게시글 댓글 1, 이모지 1

{
  "success": true,
  "data": [
    {
      "id": 2,
      "writerId": "202500001",
      "writerName": "설윤",
      "category": "free",
      "title": "Free Board Title 1",
      "content": "This is a free board content.",
      "commentCount": 1,
      "imageUrl": null,
      "createdAt": "2024-10-30T17:30:00"
    },
    {
      "id": 1,
      "writerId": "202500001",
      "writerName": "설윤",
      "category": "notice",
      "title": "Notice Title 1",
      "content": "This is a notice content.",
      "commentCount": 1,
      "imageUrl": null,
      "createdAt": "2024-10-29T21:00:00"
    },
    {
      "id": 3,
      "writerId": null,
      "writerName": "User2",
      "category": "qna",
      "title": "QnA Title 1",
      "content": "This is a QnA content.",
      "commentCount": 1,
      "imageUrl": null,
      "createdAt": "2024-11-02T23:45:00"
    }
  ]
}

1번 게시글 댓글 1, 이모지 1
2번 게시글 댓글 1, 이모지 1
3번 게시글 댓글 1, 이모지 1
-> 최신 순 정렬

{
  "success": true,
  "data": [
    {
      "id": 3,
      "writerId": null,
      "writerName": "User2",
      "category": "qna",
      "title": "QnA Title 1",
      "content": "This is a QnA content.",
      "commentCount": 1,
      "imageUrl": null,
      "createdAt": "2024-11-02T23:45:00"
    },
    {
      "id": 2,
      "writerId": "202500001",
      "writerName": "설윤",
      "category": "free",
      "title": "Free Board Title 1",
      "content": "This is a free board content.",
      "commentCount": 1,
      "imageUrl": null,
      "createdAt": "2024-10-30T17:30:00"
    },
    {
      "id": 1,
      "writerId": "202500001",
      "writerName": "설윤",
      "category": "notice",
      "title": "Notice Title 1",
      "content": "This is a notice content.",
      "commentCount": 1,
      "imageUrl": null,
      "createdAt": "2024-10-29T21:00:00"
    }
  ]
}
  • 만약 지난 주의 게시글이 size - 1개 이하일 때

11월 8일 기준 지난주는 10월 28일 ~ 11월 3일 (1, 2번)
1번 → 댓글 1개, 이모지 0개
2번 → 댓글 0개, 이모지 0개
5번, 6번, 7번 → 지지난주 핫게시글

{
  "success": true,
  "data": [
    {
      "id": 1,
      "writerId": "202500001",
      "writerName": "설윤",
      "category": "notice",
      "title": "Notice Title 1",
      "content": "This is a notice content.",
      "commentCount": 1,
      "imageUrl": null,
      "createdAt": "2024-10-29T21:00:00"
    },
    {
      "id": 2,
      "writerId": "202500001",
      "writerName": "설윤",
      "category": "free",
      "title": "Free Board Title 1",
      "content": "This is a free board content.",
      "commentCount": 0,
      "imageUrl": null,
      "createdAt": "2024-10-30T17:30:00"
    },
    {
      "id": 7,
      "writerId": "202500001",
      "writerName": "설윤",
      "category": "notice",
      "title": "Notice Title 7",
      "content": "This is a notice content.",
      "commentCount": 1,
      "imageUrl": null,
      "createdAt": "2024-10-24T21:00:00"
    }
  ]
}

@SongJaeHoonn SongJaeHoonn added the ✨ Feature 새로운 기능 명세 및 개발 label Nov 8, 2024
@SongJaeHoonn SongJaeHoonn self-assigned this Nov 8, 2024
Copy link
Collaborator

@mingmingmon mingmingmon left a comment

Choose a reason for hiding this comment

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

메소드추출을 잘 해주셔서 로직을 이해하기 편했습니다.

다만, 저와 @SongJaeHoonn님, @Jeong-Ag님이 핫 게시글 정책에 대해 회의를 했을 때,
일주일마다 핫 게시글을 새로 등재하기로 이야기 나눴던 것 같아요.

지금까지의 작업으로는 매번 API를 호출할 때마다 핫 게시글을 판단하는 쿼리문이 실행되는 것 같습니다. 즉, 일주일에 한 번 핫 게시글이 갱신 되는 것이 아니라 페이지 방문할 때마다 핫 게시글이 계속 갱신 되는 것 같아요. (물론, 게시글이 많이 올라오고, 반응도 그만큼 많이 달려야겠지만요)

이러한 동작은 저희가 처음 설계한 정책과는 조금 다른 모습이기도 하고, api 호출 시 발생하는 쿼리가 많아서 부담이 되어보입니다.

따라서 핫 게시글 선정 로직을 매주 스케쥴링을 걸어 DB에 저장해두는 방식을 제안드립니다.

@SongJaeHoonn
Copy link
Contributor Author

지금까지의 작업으로는 매번 API를 호출할 때마다 핫 게시글을 판단하는 쿼리문이 실행되는 것 같습니다. 즉, 일주일에 한 번 핫 게시글이 갱신 되는 것이 아니라 페이지 방문할 때마다 핫 게시글이 계속 갱신 되는 것 같아요. (물론, 게시글이 많이 올라오고, 반응도 그만큼 많이 달려야겠지만요)

@mingmingmon
현재 로직에서도 일주일에 한 번 핫 게시글이 갱신되고 있어요.
API를 호출할 때마다, 현재 시각을 기준으로 지난 주에 가장 반응이 많았던 핫 게시글을 조회해 가져오는 방식입니다..!

그러나 현재 방식은 API를 호출할 때마다 댓글 수와 이모지 수를 계산하는 복잡한 로직들과 복잡한 조회 방식이 요구되므로 원래의 DB에 isHotBoard 같은 새로운 칼럼을 넣어 일주일마다 스케줄링 되는 방식이 현재 구조에서는 더욱 효율적일 것 같네요!
소중한 의견 감사합니다 🙇‍♂️

@limehee limehee changed the title feat: 핫 게시글 조회 api 구현 완료 feat: 인기 게시글 기능 구현 완료 Nov 12, 2024
@limehee limehee linked an issue Nov 12, 2024 that may be closed by this pull request
1 task
@limehee
Copy link
Collaborator

limehee commented Nov 12, 2024

그러나 현재 방식은 API를 호출할 때마다 댓글 수와 이모지 수를 계산하는 복잡한 로직들과 복잡한 조회 방식이 요구되므로 원래의 DB에 isHotBoard 같은 새로운 칼럼을 넣어 일주일마다 스케줄링 되는 방식이 현재 구조에서는 더욱 효율적일 것 같네요! 소중한 의견 감사합니다 🙇‍♂️

@SongJaeHoonn 님의 제안도 효율적인 접근 방식이지만, 추가적으로 캐싱 전략을 활용하는 방안도 고려해보시면 좋을 것 같아요. 새로운 컬럼을 추가할 경우 테이블 관리와 데이터 정합성 유지가 더 복잡해질 수 있고, 매번 연산이 발생할 때마다 기존 데이터를 동기화해야 한다는 부담이 있어요.

이번 인기 게시글 기능처럼 정합성이 절대적으로 요구되지 않고 주기적으로 갱신되는 데이터라면, TTL(Time to Live) 설정이 가능한 Redis와 같은 캐시 시스템을 통해 성능을 최적화할 수 있어요. 예를 들어, 인기 게시글 정보를 Redis에 저장하고 일정 시간마다 갱신하도록 설정하면 데이터베이스 부하를 줄이면서도 빠른 응답성을 유지할 수 있어요.

또한, 현재는 카테고리와 무관하게 인기 게시글이 관리되는 것으로 보이는데, 카테고리별 인기 게시글을 도입하면 사용자에게 더욱 맞춤화된 정보를 제공할 수 있을 것으로 보여요.

@limehee
Copy link
Collaborator

limehee commented Nov 12, 2024

프론트에서 인기 게시글을 어떻게 표시할지는 모르지만, 일반 게시글과 함께 하나의 목록으로 표시된다면, 게시글 조회 시 인기 게시글 정보를 함께 반환하여 API 호출 횟수를 줄이는 방법도 고려해보시면 좋을 것 같네요.

@SongJaeHoonn
Copy link
Contributor Author

이번 인기 게시글 기능처럼 정합성이 절대적으로 요구되지 않고 주기적으로 갱신되는 데이터라면, TTL(Time to Live) 설정이 가능한 Redis와 같은 캐시 시스템을 통해 성능을 최적화할 수 있어요. 예를 들어, 인기 게시글 정보를 Redis에 저장하고 일정 시간마다 갱신하도록 설정하면 데이터베이스 부하를 줄이면서도 빠른 응답성을 유지할 수 있어요.

또한, 현재는 카테고리와 무관하게 인기 게시글이 관리되는 것으로 보이는데, 카테고리별 인기 게시글을 도입하면 사용자에게 더욱 맞춤화된 정보를 제공할 수 있을 것으로 보여요.

Redis를 사용하는 것이 익숙하지 않아 이런 방법은 생각해보지 않았는데, 인메모리로 동작하는 Redis 특성상 조회가 빠르고 DB에 부담을 주지 않아 좋을 것 같아요..! 고려해보도록 하겠습니다.

그리고, 카테고리별 인기 게시글을 생각해보긴 했지만 회의 결과 활발하지 않은 카테고리는 인기 게시글이 계속 고정되거나 아예 올라오지 않을 가능성도 고려하여 모든 카테고리에서 전체 게시글 중의 인기 게시글을 표시하기로 결정했습니다.

@mingmingmon
Copy link
Collaborator

mingmingmon commented Nov 13, 2024

프론트에서 인기 게시글을 어떻게 표시할지는 모르지만, 일반 게시글과 함께 하나의 목록으로 표시된다면, 게시글 조회 시 인기 게시글 정보를 함께 반환하여 API 호출 횟수를 줄이는 방법도 고려해보시면 좋을 것 같네요.

저는 인기 게시글 조회 API를 따로 추출하는 것이 좋을 것 같아요.

@limehee 님이 제안 주신 방식으로 구현하게 되면 페이지네이션된 결과(10개의 일반 게시글)와 다른 응답 객체(5개의 인기 게시글)을 다시 묶어서 responseDto로 반환하는 방식일 것 같은데, 제가 이해한 바가 맞을까요?

현재 일반 게시글 조회 시에 페이지네이션이 적용되어있어요. 만약 일반 게시글 조회에서 인기 게시글을 함께 반환하도록 한다면, 10개의 일반게시글 + 5개의 인기 게시글이 함께 반환되는 형태가 될 것 같습니다. 그렇게 되면 responseDto가 더욱 복잡해지고, 사용자가 페이지를 넘길 때 마다 동일한 정보인 5개의 인기 게시글이 중복해서 전달될 것 같아요.

@limehee
Copy link
Collaborator

limehee commented Nov 13, 2024

저는 인기 게시글 조회 API를 따로 추출하는 것이 좋을 것 같아요.

@limehee 님이 제안 주신 방식으로 구현하게 되면 페이지네이션된 결과(10개의 일반 게시글)와 다른 응답 객체(5개의 인기 게시글)을 다시 묶어서 responseDto로 반환하는 방식일 것 같은데, 제가 이해한 바가 맞을까요?

현재 일반 게시글 조회 시에 페이지네이션이 적용되어있어요. 만약 일반 게시글 조회에서 인기 게시글을 함께 반환하도록 한다면, 10개의 일반게시글 + 5개의 인기 게시글이 함께 반환되는 형태가 될 것 같습니다. 그렇게 되면 responseDto가 더욱 복잡해지고, 사용자가 페이지를 넘길 때 마다 동일한 정보인 5개의 인기 게시글이 중복해서 전달될 것 같아요.

제가 코드를 꼼꼼히 살펴보지 못하고 이전 코멘트에서 "일반 게시글"이라는 모호한 표현을 사용하면서 혼동을 드린 것 같아요(코멘트를 잘못 남긴 것 같습니다). 이에 따라 남겨주신 의견과 다소 어긋난 부분이 있을 수 있다는 점 양해 부탁드립니다.

retrieveHotBoards()의 반환형을 고려할 때, 커뮤니티 탭의 모아보기와 유사한 형태로 인기 게시글을 보여주고자 하는 것으로 예상돼요. 인기 게시글을 모아보기처럼 사용자에게 제공할 계획이라면, 둘의 성격이 다르므로 현재 구조대로 별도의 API로 제공하는 것이 더 적절해 보이네요. 혼동을 드린 점 다시 한번 사과드립니다.

@SongJaeHoonn
Copy link
Contributor Author

@limehee @mingmingmon
우선 질 높은 코드리뷰에 감사드리며, 제안주신 사항들 수정 및 리팩토링 완료했습니다.

변경 사항

  1. 인기 게시글 저장에 Redis 사용
  • redis에서 저장 및 조회시 RedisTemplate을 사용했습니다. (정렬 순서 문제로 인함)
  1. 일주일에 한 번만 저장되도록 스케줄링
  2. size 고정 (redis 사용으로 인함)
  3. Strategy Pattern 적용

Strategy 패턴 적용시 전략 클래스들은 일단 service 패키지에 넣어뒀는데 더 좋은 방안이 있다면 리뷰 부탁드립니다!

테스트

id 2, 3 ⇒ 지지지난주 2번 댓글 한개
id 4, 5 → 지지난주 4번 댓글 한개
id 6, 7 → 지난주
id 8 → 이번주 8번 댓글 한개
결과 : 7, 6, 5, 4, 2

{
  "success": true,
  "data": [
    {
      "id": 7,
      "writerId": "202500001",
      "writerName": "설윤",
      "category": "notice",
      "title": "Notice Title 7",
      "content": "This is a notice content.",
      "commentCount": 0,
      "imageUrl": null,
      "createdAt": "2024-11-19T21:00:00"
    },
    {
      "id": 6,
      "writerId": "202500001",
      "writerName": "설윤",
      "category": "notice",
      "title": "Notice Title 7",
      "content": "This is a notice content.",
      "commentCount": 0,
      "imageUrl": null,
      "createdAt": "2024-11-18T21:00:00"
    },
    {
      "id": 5,
      "writerId": null,
      "writerName": "User3",
      "category": "organization",
      "title": "Club News Title 1",
      "content": "This is a club news content.",
      "commentCount": 0,
      "imageUrl": null,
      "createdAt": "2024-11-12T21:00:00"
    },
    {
      "id": 4,
      "writerId": "202500003",
      "writerName": "김민지",
      "category": "graduated",
      "title": "Graduated Board Title 1",
      "content": "This is a graduated board content.",
      "commentCount": 1,
      "imageUrl": null,
      "createdAt": "2024-11-11T21:00:00"
    },
    {
      "id": 2,
      "writerId": "202500001",
      "writerName": "설윤",
      "category": "free",
      "title": "Free Board Title 1",
      "content": "This is a free board content.",
      "commentCount": 1,
      "imageUrl": null,
      "createdAt": "2024-11-04T21:00:00"
    }
  ]
}

스케줄링 후 (8번을 지난주로 옮김)
결과 : 8, 7, 6, 5, 4

{
  "success": true,
  "data": [
    {
      "id": 8,
      "writerId": "202500001",
      "writerName": "설윤",
      "category": "notice",
      "title": "Notice Title 7",
      "content": "This is a notice content.",
      "commentCount": 1,
      "imageUrl": null,
      "createdAt": "2024-11-20T22:00:00"
    },
    {
      "id": 7,
      "writerId": "202500001",
      "writerName": "설윤",
      "category": "notice",
      "title": "Notice Title 7",
      "content": "This is a notice content.",
      "commentCount": 0,
      "imageUrl": null,
      "createdAt": "2024-11-19T21:00:00"
    },
    {
      "id": 6,
      "writerId": "202500001",
      "writerName": "설윤",
      "category": "notice",
      "title": "Notice Title 7",
      "content": "This is a notice content.",
      "commentCount": 0,
      "imageUrl": null,
      "createdAt": "2024-11-18T21:00:00"
    },
    {
      "id": 5,
      "writerId": null,
      "writerName": "User3",
      "category": "organization",
      "title": "Club News Title 1",
      "content": "This is a club news content.",
      "commentCount": 0,
      "imageUrl": null,
      "createdAt": "2024-11-12T21:00:00"
    },
    {
      "id": 4,
      "writerId": "202500003",
      "writerName": "김민지",
      "category": "graduated",
      "title": "Graduated Board Title 1",
      "content": "This is a graduated board content.",
      "commentCount": 1,
      "imageUrl": null,
      "createdAt": "2024-11-11T21:00:00"
    }
  ]
}

Copy link
Collaborator

@mingmingmon mingmingmon left a comment

Choose a reason for hiding this comment

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

피드백 반영 감사합니다! 좋은 작업물로 저도 많이 배워갑니다.

Copy link
Collaborator

@limehee limehee left a comment

Choose a reason for hiding this comment

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

인기 게시글 산정 방식에 대해 전략 패턴을 적용해달라고 요청드렸었는데, 현재 코드를 확인해보니 산정 방식뿐만 아니라 요청에 따라 DB에서 데이터를 조회하고 결과를 생성하는 전체 과정을 하나의 전략으로 묶은 것처럼 보여요.
그러나, 인기 게시글 산정 로직 외의 부분은 모든 전략에서 동일하게 동작할 가능성이 높기 때문에, 산정 로직만을 전략 패턴으로 분리하는 것이 더 적합하다고 판단돼요.
또한, 클래스명이 DefaultHotBoardService로 되어 있는데, 일반적으로 전략 패턴을 구현하는 클래스명은 ___Strategy의 형태를 따르는 경우가 많아요. 클래스명을 더 명확히 변경해주세요.


요약

  1. 전략 패턴은 특정 동작만을 분리하여 캡슐화하는 데 초점이 맞춰져 있어요. 현재 코드는 전략이 과도하게 많은 역할을 맡고 있어요.
  2. 게시글 조회나 매핑같은 로직은 산정 방식과 무관하게 모든 전략에서 동일하게 작동할 가능성이 높아요. 이러한 로직은 전략이 아닌 상위 서비스에서 관리되어야 해요.
  3. DefaultHotBoardService라는 이름은 전략 패턴의 일반적인 명명 규칙(___Strategy)에 부합하지 않아요. DefaultHotBoardStrategy와 같이 역할이 더 명확히 드러나는 이름으로 변경해주세요.

참고

💠 전략(Strategy) 패턴 - 완벽 마스터하기

@SongJaeHoonn
Copy link
Contributor Author

SongJaeHoonn commented Nov 28, 2024

@limehee

피드백주신 사항 잘 이해했습니다!
변수명 변경과 클래스명 변경, 전략 패턴 책임 분리 완료했습니다. 확인 부탁드려요!

그리고 전략 패턴 책임 분리에 관해서는,
저는 전략 패턴을 적용할 때, 다른 요구사항이나 정책이 주어졌을 때 쉽게 갈아 끼울 수 있다는 점에 초점을 맞췄습니다.
따라서 인기 게시글을 redis에 저장하도록 리팩토링하기 이전에, 객체지향 5원칙중 개방-폐쇄 원칙(OCP, Open-Closed Principle)을 생각했을 때 클라이언트가 직접 전략을 선택하도록 유도해서 코드의 변경은 확실히 없도록 하되, 확장에는 열려있게 구성했었습니다.
하지만 api 호출 효율에 redis를 사용하는 것의 이점과, 인기 게시글 선정시 한 전략이 과도하게 많은 책임을 가지고 있음을 인정하고, redis를 사용하고 저장과 조회 로직을 분리하도록 리팩토링 완료했습니다.

이렇게 전략의 책임을 분리하고 나니, 컨트롤러에서는 인기게시글 선정과 저장에 관심사를 두는 것이 아니라 redis에서 조회하는 비즈니스 로직에만 연결되어 있기 때문에 인기게시글 선정에 관여할 수 없었습니다.
전략을 수정하려면 코드 내에 StrategyType만 수정하면 되긴 하지만, 수정할 부분이 한 줄밖에 안될지라도 결국 백엔드 코드를 고쳐야 하는 OCP 원칙을 위반하는 상황(확장하려면, 코드를 수정해야함)이 발생하게 됩니다.

이런 상황에서는 어떻게 코드를 작성해야 할까요?

@limehee
Copy link
Collaborator

limehee commented Nov 30, 2024

@SongJaeHoonn

전략 패턴 적용 방식에 대한 개선 방향을 제안드려요.

  1. 전략의 빈 이름을 상수로 관리
    현재 Enum을 사용해 전략을 관리하고 있는데, Enum을 상수로 변경하면 상수를 이용해서 전략 식별자를 관리할 수 있어요. 이렇게 하면 전략 식별자를 중앙에서 일관되게 관리하고, 오탈자를 방지하면서, 변경 시 수정 범위를 최소화할 수 있어요.

새로운 전략을 추가할 때 StrategyConstants에 상수를 추가해야 하므로 엄밀히 말해 OCP를 완벽히 준수하지는 못해요.
하지만 이 방식은 값과 동작을 분리하고 의존성을 줄여 변경 용이성과 유지보수성을 개선할 수 있어요.

  1. 전략을 Map 형태로 관리
    전략 빈을 Map<String, HotBoardSelectionStrategy> 형태로 주입받아 관리하면, 새로운 전략이 추가되더라도 컨테이너가 자동으로 맵에 포함시켜 주기 때문에 별도의 추가 작업이 필요 없게 돼요.

  2. Redis와 전략 연계
    현재 캐싱 구조도 잘 설계되어 있지만, 전략별로 Redis 키를 분리해서 관리하면 여러 전략 간 데이터 충돌 없이 명확하게 관리할 수 있어요.
    Redis 키를 {prefix}:{strategyName} 형태로 구성하는 방식을 추천드려요.

  • 클라이언트 요청 시 전략을 파라미터로 함께 받아, 해당 전략을 활용해 Redis에서 데이터를 조회해주세요.
  • Redis에서 값을 조회했을 때 데이터가 없을 경우, 전략에 따라 데이터를 선정하고 Redis에 저장하는 로직으로 개선하면 성능과 확장성을 모두 확보할 수 있어요.
  1. OCP(Open-Closed Principle)에 대한 의견
    현재 방식에서 Enum 기반 StrategyType을 사용하는 것은 새로운 전략 추가 시 Enum 값을 변경해야 하므로 OCP를 완전히 만족하지 못할 수 있어요.
    하지만, 상수와 Map을 활용하면 기존 코드를 수정하지 않고도 새로운 전략을 추가할 수 있도록 설계되어 OCP 준수 측면에서 더 나은 선택이 될 수 있어요.

관련 구현 사례

제가 이전에 구현했던 전략 패턴 기반 코드가 현재 논의 중인 설계와 유사한 점이 많아, 참고하실 수 있도록 공유드려요.

https://github.com/limehee/ngram-similarity-search/blob/main/NGramSimilarityService.java
https://github.com/limehee/ngram-similarity-search/tree/main/similarity

해당 코드는 유사도 계산에 다양한 알고리즘을 적용하기 위해 전략 패턴을 활용한 구현 사례에요. 현재 설계에서 참고할만한 부분은 다음과 같아요.

  1. 전략 등록 및 선택 방식
    전략을 Map<String, SimilarityStrategy> 형태로 관리하여, 이름을 통해 동적으로 전략을 선택할 수 있도록 설계했어요. 새로운 전략을 추가해도 기존 코드를 수정할 필요 없이 확장이 가능해요. 현재 설계에서도 비슷한 방식으로 전략을 관리하면 확장성과 유지보수성을 모두 가져갈 수 있어요.

  2. 기본 전략 설정
    전략 이름이 없거나 잘못된 이름이 전달된 경우 기본 전략을 반환하도록 설정하여 안정성을 높였어요. 현재 설계에서도 동일하게 기본 전략을 지정하면 잘못된 요청에도 유연하게 대응할 수 있을 거예요.

  3. 캐싱 활용
    참고 코드에서는 Redis 대신 Caffeine 캐시를 사용했지만, 데이터를 조회하고 계산 결과를 캐싱하는 구조는 유사해요. 참고 코드에서 사용된 방식이 인기 게시글 선정 로직을 분리하면서 성능을 최적화하는 데 도움이 될 거예요.

  4. OCP 준수 설계
    새로운 전략 추가 시 기존 코드를 수정하지 않고 전략 구현체와 상수를 추가하는 방식으로 OCP를 준수했어요.
    현재 논의 중인 설계에서도 유연함을 더하는 데 도움이 될 거예요.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
✨ Feature 새로운 기능 명세 및 개발
Projects
None yet
Development

Successfully merging this pull request may close these issues.

인기 게시글 기능 구현
3 participants