인프런 영문 브랜드 로고
인프런 영문 브랜드 로고

인프런 커뮤니티 질문&답변

최재량님의 프로필 이미지

작성한 질문수

스프링부트 JUnit 테스트 - 시큐리티를 활용한 Bank 애플리케이션

요청/응답 DTO 관련 문의

작성

·

29

0

안녕하세요, dto 관련 문의드립니다.

 

요청/응답 DTO를 왜 static으로 만드나요?

이전 데이터가 유지되지 않나요?? 매번 객체를 만들면 안되나요?

 

@Getter
@Setter
public static class AccountWithdrawReqDto {
    @NotNull
    @Digits(integer = 4, fraction = 4)
    private Long number;
    @NotNull
    @Digits(integer = 4, fraction = 4)
    private Long password;
    @NotNull
    private Long amount;
    @NotEmpty
    @Pattern(regexp = "^(WITHDRAW)$")
    private String transactionType;
}
//ATM -> 계좌
    @Transactional
    public AccountWithdrawRespDto 계좌출금(AccountWithdrawReqDto accountWithdrawReqDto, Long userId) {
        //1. 0원 체크
        if (accountWithdrawReqDto.getAmount() <= 0L)
            throw new CustomApiException("0원 이하의 금액을 출금할 수 없습니다.");

        //2. 출금 계좌 확인
        Account withdrawAccountPS = accountRepository.findByNumber(accountWithdrawReqDto.getNumber())
                .orElseThrow(() -> new CustomApiException("계좌를 찾을 수 없습니다."));

        //3. 본인 확인
        withdrawAccountPS.checkOwner(userId);

        //4. 패스워드 확인
        withdrawAccountPS.checkPassword(accountWithdrawReqDto.getPassword());

        //5. 출금계좌 잔액 확인
//        withdrawAccountPS.checkBalance(accountWithdrawReqDto.getAmount());

        //6. 출금 (잔액 확인이 누락되면 안되므로 출금 메소드에 녹인다!)
        withdrawAccountPS.withdraw(accountWithdrawReqDto.getAmount());

        //7. 거래 내역
        Transaction transaction = Transaction.builder()
                .withdrawAccount(withdrawAccountPS)
                .depositAccount(null)
                .withdrawAccountBalance(withdrawAccountPS.getBalance())
                .depositAccountBalance(null)
                .amount(accountWithdrawReqDto.getAmount())
                .sender(withdrawAccountPS.getNumber().toString())
                .receiver("ATM")
                .transactionType(TransactionEnum.WITHDRAW)
                .build();
        Transaction transactionPS = transactionRepository.save(transaction);

        return new AccountWithdrawRespDto(withdrawAccountPS, transactionPS);
    }

답변 2

0

최주호님의 프로필 이미지
최주호
지식공유자

static으로 생성하면, 파일 생성에 일관성이 생겨서 좋습니다.

이름짓기 좋아요!!

그리고, static으로 정의된 클래스 이름만 외부에 노출되면, new를 해야 객체가 생기고

더이상 힙을 참조하지 않으면 메모리에서 소멸됩니다.

0

인프런 AI 인턴님의 프로필 이미지

안녕하세요, 인프런 AI 인턴입니다.

님의 질문은 스프링 부트에서 DTO 클래스들을 static으로 선언하는 이유와 일반적으로 객체를 매번 생성하지 않는 이유에 대한 내용으로 이해됩니다. 이 부분에 대해 설명드리겠습니다.

왜 DTO를 static으로 만드는가?

DTO(Data Transfer Object)는 계층 간 데이터를 주고받기 위한 객체로, 기본적으로 데이터만 보유하며 메서드를 포함하지 않는 간단한 클래스입니다. DTO를 static으로 만드는 주요 이유 중 하나는 여러 DTO 클래스를 하나의 외부 클래스 내에 그룹핑하는 것입니다. 이렇게 하면 관련된 모든 DTO를 한 파일에 담아 가독성과 관리가 용이해집니다.

이전 데이터 유지 문제

DTO는 기본적으로 데이터를 담기 위한 객체이므로, 각 요청마다 새롭게 객체를 생성하여 사용하는 것이 일반적입니다. static으로 선언했을 때의 혼동 요소와 구분할 필요가 있습니다. 클래스 내부에 static으로 정의된 DTO 클래스는 그 자체가 하나의 정적 유틸리티 메서드처럼 객체를 생성하지 않고 접근할 때 유용하며, 기본적으로 데이터가 인스턴스 간에 공유되지는 않습니다. 따라서 데이터가 이전 요청에서 유지되지 않고, 각 사용 시점에 데이터 객체가 독립적으로 생성됩니다.

객체 매번 생성 문제

매번 새로운 DTO 객체를 생성하여 요청이나 응답에 사용합니다. 이는 MVC 패턴에서는 자연스러운 행위로, 각 요청은 독립적인 트랜잭션으로 간주되며 서버의 멀티 스레드 환경에서 각 클라이언트의 요청/응답 데이터는 분리되어 관리되기 때문입니다. static은 데이터의 공유 목적이 아니라 객체 구조의 이해와 접근 편의를 높이기 위한 것입니다.

관련 내용에 대한 더 많은 정보를 원하신다면 기존의 DTO 사용과 관련한 게시물를 참고하시면 도움이 될 것입니다.

저는 질문자님의 이해를 돕고자 지식공유자님의 기존 답변을 참고하여 유사한 답변 링크를 추천해드리고 있습니다.
현재 베타 기능으로 답변이 만족스럽지 않을 수 있는 점 양해 부탁드립니다. 🙏
추가적으로 궁금한 점이 있으시면, 이어서 질문해 주세요. 곧 지식공유자께서 답변해 주실 것입니다.