카테고리 없음

Static Factory Method (정적 팩토리 메서드)

ddh1713 2024. 9. 23. 14:09
1. Static Factory Method
@Getter
@Entity
@Table(name = "menu_tb")
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@EntityListeners(AuditingEntityListener.class)
public class Menu {
    // 필요한 필드 : 메뉴명, 가격, 연관된 가게,
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private String name;

    @Column
    @NotNull
    private int price;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "store_id", nullable = false)
    private Store store;

    @LastModifiedDate
    @Column
    @Temporal(TemporalType.TIMESTAMP)
    private LocalDateTime updatedAt;

    @Column
    @Temporal(TemporalType.TIMESTAMP)
    private LocalDateTime deletedAt;

    private Menu(String name, int price, Store store) {
        this.name = name;
        this.price = price;
        this.store = store;
    }

    public static Menu from(MenuRequest menuRequest, Store store) {
        return new Menu(
                menuRequest.getName(),
                menuRequest.getPrice(),
                store
        );
    }

    public void updateMenu(String name, int price) {
        this.name = name;
        this.price = price;
    }
}

 

이제껏 배워온 경험으로는 Menu Entity 안에 Menu 생성자를 만들고 그대로 써줬었습니다. 하지만, 이번 프로젝트 협업 과정을 통해서 Menu 에 대한 팩토리 메서드를 생성하는 것을 배웠습니다.

 

 생성자를 public 으로 만들지 않고, 따로 static 메서드를 사용하여 객체를 생성하는 이유는 주로 객체 생성의 통제를 강화하고, 가독성을 높이기 위해서 입니다. 좀 더 구체적으로 설명하면,

 

[1] 불변성 및 캡슐화 강화

 

 public 생성자를 사용하는 경우, 객체를 생성하는 방식에 대한 통제가 줄어듭니다. 아무나 생성자를 호출할 수 있어, 원하는 값으로 객체가 생성될 수 있는 반면, 이로 인해 객체의 상태가 일관되지 않거나, 예상치 못한 방식으로 설정될 위험이 있습니다. 반면에 private 또는 protected 생성자를 사용하면, 외부에서 직접 생성자를 호출할 수 없고, 대신 개발자가 제공하는 팩토리 메서드( static  from (...) ) 를 통해서만 객체를 생성할 수 있습니다. 이를 통해 객체 생성 과정에서 추가적인 검증이나 복잡한 로직을 넣을 수 있고, 객체가 항상 일관된 상태로 생성되도록 보장할 수 있습니다.

 

[2] 팩토리 메서드 패턴 (Factory Method Pattern)

 

 static 메서드인 from 을 사용하는 것은 팩토리 메서드 패턴의 일종입니다. 이 패턴을 사용하면, 객체 생성 시 더 명확하고 가독성 있는 코드를 작성할 수 있습니다. 예를 들어 new Menu() 와 같은 방식보다 Menu.from() 방식이 의도를 더 잘 드러냅니다. 특히, 생성 매개변수들이 많거나 복잡할 때 가독성을 크게 개선할 수 있습니다.

 

[3] 유연한 객체 생성 가능

 

 팩토리 메서드를 사용하면, 다양한 객체 생성 전략을 적용할 수 있습니다. 예를 들어, 필요에 따라 같은 팩토리 메서드에서 다른 종류의 객체를 반환하거나, 특정 조건에 따라 다른 로직을 통해 객체를 생성할 수 있습니다. 이렇게 하면 생성자를 오버로딩할 필요 없이 객체 생성 방식을 쉽게 확장할 수 있습니다.

 

[4] 의미 있는 이름 부여 가능

 

 팩토리 메서드는 객체 생성과 관련된 의미 있는 이름을 부여할 수 있습니다. Menu.from(...) 와 같은 이름을 사용하면 코드의 의도가 명확해집니다. new Menu(...) 라는 표현은 단순히 객체를 생성하는 것을 보여주지만, from() 이라는 메서드는 객체를 어떤 입력으로 부터 생성한다는 의미를 전달하여 가독성을 높입니다.

 

[5] 테스트 코드 작성의 용이성

 

 객체 생성을 팩토리 메서드를 통해 제어함으로써, 추후 테스트 코드 작성할 때도 더 용이하게 객체를 생성하고 관리할 수 있습니다.