본문 바로가기
개인 공부용 프로젝트/crud.jpa.api

템플릿 메서드 -> 전략 패턴

by pon9 2025. 1. 3.
public interface BoardStrategy<U> {

    BoardResponseDto createPost(BoardRequestDto dto, U userInfo);

    BoardResponseDto updatePost(BoardRequestDto dto, U userInfo, Long id);

    void deletePost(U userInfo, Long id);

    CommentResponseDto createComment(Long boardId, CommentRequestDto dto, U userInfo);

    void deleteComment(Long boardId, Long commentId, U userInfo);
}

기존의 템플릿 메서드 패턴에서 전략 패턴으로 구조를 바꿔보았다. 익명 사용자와 비익명 사용자 간의 로직이 극명하게 다를 때 템플릿메서드 같은 경우에선 좀 조절하기 힘든 부분이 있었다.

crud는 이제 boardStrategy를 구현하면 된다.

@Service
@RequiredArgsConstructor
public class BoardService {

    private final BoardAsyncService boardAsyncService;
    private final BoardSearchPagingService boardSearchPagingService;
    private final BoardRepository boardRepository;

    //readPost
    public BoardReadResponseDto readPost(Long id, int page, int size){
        Board board = getBoard(id);
        boardAsyncService.updateViewCountAsync(id);

        Page<CommentResponseDto> comments = boardSearchPagingService.pagingComments(id, page, size);
        return BoardMapper.toReadDto(board, comments);
    }

    //likePost
    @Transactional
    public BoardResponseDto likePost(Long id) {
        Board board = getBoard(id);

        board.updateLiked();
        return BoardMapper.toDto(board);
    }

    //helper
    private Board getBoard(Long id) {
        return boardRepository.findById(id)
                .orElseThrow(() -> new CustomException(ErrorCode.CONTENT_NOT_FOUND));
    }
}

그리고 단순한 like 나 read 로직은 익명이든 비익명이든 동일한 서비스이기 때문에 클래스를 분리했다.

 

문제는 익명 사용자의 정보를 또다른 dto로 받아오면서 시작됐는데..

@PostMapping
public ResponseEntity<BoardResponseDto> createPost(
       HttpServletRequest req,
       @Valid @RequestBody BoardRequestDto dto,
       @RequestHeader(required = false) AnonymousRequestDto anonymous
){
    Long sessionUserId = (Long) req.getSession().getAttribute("userId");

    BoardResponseDto board = sessionCheckingService.CreatePost(sessionUserId, dto, anonymous);

    return ResponseEntity.ok(board);
}

골치아프다 흠.. header로 익명 사용자의 요청을 불러오게 되는 바람에 유지보수도 어려워지고 쓸데없는 converter 설정을 해야 되게 생겼다

그냥 anonymous를 boardRequestDto가 상속받아서 사용하게 할지.. dto구조를 어떻게 할지 고민을 좀 해야겠다.