본문 바로가기

IT좋은지식

생성자 보단 정적 팩토리 메서드! (왜 정적 생성자를 통해 객체를 생성하는것이 안티패턴인가?)

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

  • 객체 생성 시 캡슐화 한다.
  • 객체를 생성하는 역할을 하는 클래스 메서드이다.
  • GoF 디자인 패턴 중 팩토리 패턴에서 유래한 이 단어는 객체를 생성하는 역할을 분리하겠다는 취지가 담겨있다.

생성자와의 차이는?

  • 이름을 가질 수 있다.
    • 생성자를 통한 생성
    •  
    • Character warrior = new Character(5, 15, 20, 3); Character mage = new Character(15, 5, 10, 15);
    • 정적 팩토리 메서드를 통한 생성
    • Character warrior = Character.newWarrior();
      Character mage = Character.newMage();
  • 호출할때 마다 객체를 생성할 필요가 없다.
    • public static BigInteger valueOf(long val) {
          // 미리 만들어둔 객체를 리턴한다
          if (val == 0)
              return ZERO;
          if (val > 0 && val <= MAX_CONSTANT)
              return posConst[(int) val];
          else if (val < 0 && val >= -MAX_CONSTANT)
              return negConst[(int) -val];
      
          // 새로운 객체를 만들어 리턴한다
          return new BigInteger(val);
      }
  • 하위 자료형 객체를 반환할 수 있다.
    •     public static Discount createDiscountItem(String discountCode) throws Exception {
              if(!isValidCode(discountCode)) {
                  throw new Exception("잘못된 할인 코드");
              }
              // 쿠폰 코드인가? 포인트 코드인가?
              if(isUsableCoupon(discountCode)) {
                  return new Coupon(1000);
              } else if(isUsablePoint(discountCode)) {
                  return new Point(500);
              }
              throw new Exception("이미 사용한 코드");
          }
  • 객체 생성을 캡슐화 할 수 있다.
    • package com.tiggle.web;
      
      public class User {
          private Long userId;
          private String username;
          private Boolean acticve;
      
          public User() {
          }
      
          public User(String username, String username1, boolean b) {
              //...생략
          }
      
          public static <T> User from(T user) {
              if (user instanceof InactiveUser) {
                  return new User(((InactiveUser) user).getUsername(), ((InactiveUser) user).getUsername(), false);
              } else {
                  return new User(((InactiveUser) user).getUsername(), ((InactiveUser) user).getUsername(), true);
              }
          }
      
          public class InactiveUser {
              private Long userId;
              private String username;
      
              public Long getUserId() {
                  return userId;
              }
      
              public void setUserId(Long userId) {
                  this.userId = userId;
              }
      
              public String getUsername() {
                  return username;
              }
      
              public void setUsername(String username) {
                  this.username = username;
              }
          }
      
          public void main(String a[]) {
              InactiveUser inactiveUser = new InactiveUser();
              inactiveUser.setUserId(1L);
              inactiveUser.setUsername("변진환");
      
              User user = new User(1L, "변진환", true); //생성자
              User user2 = User.from(inactiveUser); //정적 메소드
          }
      }

정정 팩토리 메서드 네이밍 컨벤션

  • from : 하나의 매개 변수를 받아서 객체를 생성.
  • of : 여러개의 매개 변수를 받아서 객체를 생성.
  • getInstance / instance : 인스턴스를 생성, 이전에 반환했던 것과 같을 수 있음.
  • newInstance / create : 새로운 인스턴스를 생성.
  • get[OtherType] : 다른 타입의 인스턴스를 생성, 이전에 반환했던 것과 같을 수 있음.
  • new[OtherType] :다른 타입의 새로운 인스턴스를 생성.

장/단점

  • 장점
    1. 이름이 있으므로 생성자에 비해 가독성이 좋다.
    2. 호출할 때마다 새로운 객체를 생성할 필요가 없다.
    3. 하위 자료형 객체를 반환할 수 있다.
    4. 형인자 자료형(parameterized type) 객체를 만들 때 편하다.
  • 단점
    1. 정적 팩토리 메서드만 있는 클래스라면, 생성자가 없으므로 하위 클래스를 못 만든다.
    2. 정적 팩토리 메서드는 다른 정적 메서드와 잘 구분되지 않는다. (문서만으로 확인하기 어려울 수 있음)

끝으로...

분명 장단점이 있을 것이다.

예를 들어 무조건 생성자를 생성해서 사용하는 객체가 있다고 하자 그럼 이 패턴을 사용해야할까? 의문점이 들기도 한다.

아직 허접이라 그럴 수 도 있는데 많이 사용해서 써보고 좋은 점을 찾아 가도록 하자.

 


관련 자료

https://velog.io/@ljinsk3/%EC%A0%95%EC%A0%81-%ED%8C%A9%ED%86%A0%EB%A6%AC-%EB%A9%94%EC%84%9C%EB%93%9C%EB%8A%94-%EC%99%9C-%EC%82%AC%EC%9A%A9%ED%95%A0%EA%B9%8C

 

정적 팩토리 메서드는 왜 사용할까?

정적 팩토리 메서드를 들어본 적이 있는가? 프로그래밍을 시작한 지 얼마 안된 사람도 정적 팩토리 메서드라는 단어를 한번쯤은 들어봤을 것이다. 그리고 아마 프로그래밍을 조금 해본 사람들

velog.io

https://johngrib.github.io/wiki/static-factory-method-pattern/

'IT좋은지식' 카테고리의 다른 글

로컬 개발 환경으로 웹서비스로 공유하기  (0) 2022.12.16
WebP 란?  (0) 2022.06.12
REST API  (0) 2022.02.16
Event Driven 이란?  (0) 2021.04.28
HTTP 접근제어 (CORS)란?  (0) 2020.01.30