게시판 setter 수정 개선하기

이상혁·2024년 4월 24일
0

문제 상황

게시판을 맡아서 개발을 하던 중 @setter 어노테이션을 통해서 게시판의 제목과 내용을 수정을 하였다.
그런데 구글링을 통해서 알아보니 @setter를 이용한 수정은 지양을 해야 한다고 한다.

지양을 해야 하는 이유는
첫 번째, 변경되지 않아야 할 값이 변경이 될 가능성이 있다.
엔티티에서는 id 즉, 엔티티를 구분하는 고유한 값이 있다.
이 값은 하나의 엔티티마다 다 다르며 엔티티마다 고유한 값을 가진다.
그런데 @setter를 사용하게 되면 id가 변경이 되는 setter메소드도 만들어지기 때문에 setter메소드를 통해서 고유한 값이 변경이 될 수도 있다.

두 번째, 객체지향에 위배되는 방법이다.
객체지향 중 갭슐화에 위배가 된다.
갭슐화는 데이터와 그 데이터를 다루는 메서드를 하나로 묶는 것을 말한다.
이를 통해서 데이터의 일관성을 유지하고 외부의 접근을 막아서 내부 구현을 숨기도록 하는 것입니다.
하지만 @setter는 모든 필드에 대해서 외부에서 변경이 가능하기 때문에 위배가 된다.

이러한 두 가지 이유로 @setter로 수정을 구현했던 부분을 개선하고자 한다.

해결 방법

package com.github.riset_backend.writeBoard.board.entity;

import com.github.riset_backend.login.employee.entity.Employee;
import com.github.riset_backend.writeBoard.board.dto.BoardRequestDto;
import com.github.riset_backend.writeBoard.boardFile.entity.BoardFile;
import com.github.riset_backend.writeBoard.reply.entity.Reply;
import jakarta.persistence.*;
import lombok.*;
import org.hibernate.annotations.DynamicUpdate;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

@Getter
@Setter
@Builder
@AllArgsConstructor
@NoArgsConstructor
@Entity
@Table(name = "board")
@EntityListeners(AuditingEntityListener.class)
@DynamicUpdate
public class Board  {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "board_no")
    private Long boardNo;

    @ManyToOne
    @JoinColumn(name = "employee_no")
    private Employee employee;

    @Column(name = "title")
    private String title;

    @Column(name = "content")
    private String content;

    @CreatedDate
    @Column(updatable = false)
    private LocalDateTime createAt;

    @Column(name = "deleted")
    private String deleted;

    @OneToMany(mappedBy = "board", fetch = FetchType.LAZY)
    private List<BoardFile> boardFiles;

    @OneToMany(mappedBy = "board", fetch = FetchType.LAZY)
    private List<Reply> replies;

    public Board(Long boardNo) {
        this.boardNo = boardNo;
    }

}
if(boardRequestDto.getContent() != null) {
	board.setContent(boardRequestDto.getContent());
}

if(boardRequestDto.getTitle() != null) {
	board.setTitle(boardRequestDto.getTitle());
}

@Setter라는 어노테이션을 엔티티에 붙혀주고 있다.
그리고 service에서 setter 메소드를 통해서 수정을 해주고 있다.
이 방법으로도 수정이 가능하지만 외부에서 접근이 너무 쉽고 객체지향적이지 못한 부분이다.

package com.github.riset_backend.writeBoard.board.entity;

import com.github.riset_backend.login.employee.entity.Employee;
import com.github.riset_backend.writeBoard.board.dto.BoardRequestDto;
import com.github.riset_backend.writeBoard.boardFile.entity.BoardFile;
import com.github.riset_backend.writeBoard.reply.entity.Reply;
import jakarta.persistence.*;
import lombok.*;
import org.hibernate.annotations.DynamicUpdate;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

@Getter
@Builder
@AllArgsConstructor
@NoArgsConstructor
@Entity
@Table(name = "board")
@EntityListeners(AuditingEntityListener.class)
@DynamicUpdate
public class Board  {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "board_no")
    private Long boardNo;

    @ManyToOne
    @JoinColumn(name = "employee_no")
    private Employee employee;

    @Column(name = "title")
    private String title;

    @Column(name = "content")
    private String content;

    @CreatedDate
    @Column(updatable = false)
    private LocalDateTime createAt;

    @Column(name = "deleted")
    private String deleted;

    @OneToMany(mappedBy = "board", fetch = FetchType.LAZY)
    private List<BoardFile> boardFiles;

    @OneToMany(mappedBy = "board", fetch = FetchType.LAZY)
    private List<Reply> replies;

    public Board(Long boardNo) {
        this.boardNo = boardNo;
    }

    public Board updateBoard(BoardRequestDto boardRequestDto) {
        if (boardRequestDto.getTitle() != null) {
            this.title = boardRequestDto.getTitle();
        }
        if (boardRequestDto.getContent() != null) {
            this.content = boardRequestDto.getContent();
        }
        return this;
    }
}

엔티티 안에 수정 메소그를 만들어서 이 메소드를 통해서 수정을 해준다.
이 방법을 사용하면 모든 필드에 대해서 수정이 가능한 메소드가 생기는 것이 아니라 필요한 필드에 대해서만 수정이 가능하다.
따라서 첫 번째인 고유한 값이 변경이 되는 우려가 없어지고 객체지향을 위배하는 일이 없어진다.

profile
개발 공부 하기 위해 만든 블로그

0개의 댓글