Spring Boot

메서드 체이닝과 빌더 패턴을 활용한 엔티티 클래스 구현

청춘고양이 2024. 6. 24. 11:11
반응형

1. 개요

스프링(Spring) 프레임워크에서 데이터베이스와 상호작용하는 엔티티(Entity) 클래스는 애플리케이션의 중요한 부분입니다. 메서드 체이닝(Method Chaining)과 빌더 패턴(Builder Pattern)을 활용하여 엔티티 클래스를 구현하면 가독성을 높이고 유지보수를 용이하게 할 수 있습니다. 하지만 이러한 내용을 다룬 포스팅이 많지 않아, 이 글을 통해 해당 주제를 다루고자 합니다. 이번 글에서는 ArticleEntity 클래스를 예로 들어 메서드 체이닝과 빌더 패턴을 적용하는 방법을 설명합니다.

2. ArticleEntity 클래스 개요

ArticleEntity 클래스는 게시물(Article)을 표현하는 엔티티로, 게시물의 ID, 작성자 이메일, 작성일, 제목, 내용 등 다양한 속성을 포함합니다. 이 클래스는 IEntity 인터페이스를 구현하여, 메서드 체이닝을 통해 객체를 생성하고 수정할 수 있도록 설계되었습니다.

3. 메서드 체이닝과 빌더 패턴 적용

메서드 체이닝은 각 메서드가 자신을 반환하여 연속된 호출을 가능하게 하는 방식입니다. 빌더 패턴은 복잡한 객체를 생성하는 방법을 제공하여, 객체 생성 시 코드의 가독성을 높여줍니다.

3.1. 기본 구조

public class ArticleEntity implements IEntity<ArticleEntity> {

    // 상수
    public static final String ATTRIBUTE_NAME = "accompanyArticle";
    public static final String ATTRIBUTE_NAME_PLURAL = "accompanyArticles";

    // 속성
    private int index;
    private String userEmail;
    private Date createdAt;
    private String continentValue;
    private String countryValue;
    private String regionValue;
    private int capacity;
    private Date dateFrom;
    private Date dateTo;
    private byte[] coverImage;
    private String coverImageMime;
    private String title;
    private String content;
    private int viewCount;

    // 기본 생성자
    public ArticleEntity() {
    }

    // 매개변수가 있는 생성자
    public ArticleEntity(int index, String userEmail, Date createdAt, String continentValue, String countryValue, String regionValue, int capacity, Date dateFrom, Date dateTo, byte[] coverImage, String coverImageMime, String title, String content, int viewCount) {
        this.index = index;
        this.userEmail = userEmail;
        this.createdAt = createdAt;
        this.continentValue = continentValue;
        this.countryValue = countryValue;
        this.regionValue = regionValue;
        this.capacity = capacity;
        this.dateFrom = dateFrom;
        this.dateTo = dateTo;
        this.coverImage = coverImage;
        this.coverImageMime = coverImageMime;
        this.title = title;
        this.content = content;
        this.viewCount = viewCount;
    }

    // 빌더 패턴을 위한 빌드 메서드
    public static ArticleEntity build() {
        return new ArticleEntity();
    }

    // Getter와 Setter
    public int getIndex() {
        return index;
    }

    public ArticleEntity setIndex(int index) {
        this.index = index;
        return this;
    }

    public String getUserEmail() {
        return userEmail;
    }

    public ArticleEntity setUserEmail(String userEmail) {
        this.userEmail = userEmail;
        return this;
    }

    public Date getCreatedAt() {
        return createdAt;
    }

    public ArticleEntity setCreatedAt(Date createdAt) {
        this.createdAt = createdAt;
        return this;
    }

    public String getContinentValue() {
        return continentValue;
    }

    public ArticleEntity setContinentValue(String continentValue) {
        this.continentValue = continentValue;
        return this;
    }

    public String getCountryValue() {
        return countryValue;
    }

    public ArticleEntity setCountryValue(String countryValue) {
        this.countryValue = countryValue;
        return this;
    }

    public String getRegionValue() {
        return regionValue;
    }

    public ArticleEntity setRegionValue(String regionValue) {
        this.regionValue = regionValue;
        return this;
    }

    public int getCapacity() {
        return capacity;
    }

    public ArticleEntity setCapacity(int capacity) {
        this.capacity = capacity;
        return this;
    }

    public Date getDateFrom() {
        return dateFrom;
    }

    public ArticleEntity setDateFrom(Date dateFrom) {
        this.dateFrom = dateFrom;
        return this;
    }

    public Date getDateTo() {
        return dateTo;
    }

    public ArticleEntity setDateTo(Date dateTo) {
        this.dateTo = dateTo;
        return this;
    }

    public byte[] getCoverImage() {
        return coverImage;
    }

    public ArticleEntity setCoverImage(byte[] coverImage) {
        this.coverImage = coverImage;
        return this;
    }

    public String getCoverImageMime() {
        return coverImageMime;
    }

    public ArticleEntity setCoverImageMime(String coverImageMime) {
        this.coverImageMime = coverImageMime;
        return this;
    }

    public String getTitle() {
        return title;
    }

    public ArticleEntity setTitle(String title) {
        this.title = title;
        return this;
    }

    public String getContent() {
        return content;
    }

    public ArticleEntity setContent(String content) {
        this.content = content;
        return this;
    }

    public int getViewCount() {
        return viewCount;
    }

    public ArticleEntity setViewCount(int viewCount) {
        this.viewCount = viewCount;
        return this;
    }

    // equals, hashCode, clone, copyValuesOf 메서드
    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        ArticleEntity that = (ArticleEntity) o;
        return index == that.index;
    }

    @Override
    public int hashCode() {
        return Objects.hash(index);
    }

    @Override
    public ArticleEntity clone() {
        ArticleEntity articleEntity = new ArticleEntity();
        this.index = articleEntity.index;
        this.userEmail = articleEntity.userEmail;
        this.createdAt = articleEntity.createdAt;
        this.continentValue = articleEntity.continentValue;
        this.countryValue = articleEntity.countryValue;
        this.regionValue = articleEntity.regionValue;
        this.capacity = articleEntity.capacity;
        this.dateFrom = articleEntity.dateFrom;
        this.dateTo = articleEntity.dateTo;
        this.coverImage = articleEntity.coverImage;
        this.coverImageMime = articleEntity.coverImageMime;
        this.title = articleEntity.title;
        this.content = articleEntity.content;
        this.viewCount = articleEntity.viewCount;
        return articleEntity;
    }

    @Override
    public void copyValuesOf(ArticleEntity articleEntity) {
        articleEntity.index = this.index;
        articleEntity.userEmail = this.userEmail;
        articleEntity.createdAt = this.createdAt;
        articleEntity.continentValue = this.continentValue;
        articleEntity.countryValue = this.countryValue;
        articleEntity.regionValue = this.regionValue;
        articleEntity.capacity = this.capacity;
        articleEntity.dateFrom = this.dateFrom;
        articleEntity.dateTo = this.dateTo;
        articleEntity.coverImage = this.coverImage;
        articleEntity.coverImageMime = this.coverImageMime;
        articleEntity.title = this.title;
        articleEntity.content = this.content;
        articleEntity.viewCount = this.viewCount;
    }
}

위 예시에서는 ArticleEntity 객체를 메서드 체이닝을 통해 간결하게 생성하고 초기화합니다.

6. 결론

메서드 체이닝과 빌더 패턴을 활용하면 엔티티 클래스를 보다 읽기 쉽고 유지보수하기 쉽게 만들 수 있습니다. ArticleEntity 클래스는 이러한 접근 방식을 잘 보여주는 예로, 스프링 프로젝트에서 데이터베이스와 상호작용할 때 유용하게 사용될 수 있습니다.

 

반응형