[TIL] 정적 팩토리 메서드, 모놀로닉 아키텍쳐

2025-04-29 TIL

📝 TIL (Today I Learned)
🔗 원본 이슈: #48
📅 작성일: 2025-04-29
🔄 최종 수정: 2025년 05월 20일


🍀 새롭게 배운 것

정적 팩토리 메서드 (static factory method)

  • 클래스의 public 생성자로 객체를 생상하는 것이 아닌, 메서드를 통해 객체를 생성하는 것
  • 에러를 조기에 발생시키고 객체 생성 과정에서 잘못된 인자나 누락된 필드 등으로 인한 문제를 “컴파일 타임”에 더 쉽게 잡을 수 있게 도와준다.
    • 생성자를 사용할 경우
      •   User user = new User("nano"); // 컴파일은 되지만, 런타임에 NullPointerException 가능
        
      • 생성자의 시그니쳐가 여러 개 있거나, 필드가 많고 순서가 헷갈리는 경우,
        • 컴파일러는 단순히 시그니처가 맞으면 OK 판단
        • 잘못된 값, 누락된 필드 등은 컴파일러가 알 수 없고, 런타임 에러로 이어짐
    • 정적 팩토리 메서드를 사용할 경우
      • null, 잘못된 형식, 비즈니스 룰 위반 등을 검증하는 방어적 메서드 내부에서 체크 가능함
      •   public static User of(String username, String email) {
              if (username == null || email == null) {
                  throw new IllegalArgumentException("username과 email은 필수입니다.");
              }
              return new User(username, email);
          }
        
      • 에러를 조기에 발생시키고 명확한 메시지를 제공할 수 있음
  • 장점 (“이펙티브 자바” 책 참고)
    1. 이름을 가질 수 있다.
      • 생성자에 넘기는 매개변수와 생성자 자체만으로는 반환될 객체의 특성을 제대로 설명하기 힘들다.
      • new라는 키워드를 통해 객체를 생성하는 생성자는 내부 구조를 잘 알고 있어야 목적에 맞게 객체를 생성할 수 있다.

        BigInteger(int, int, Random)

      • 정적 팩토리 메서드는 객체의 특성을 설명할 이름을 붙일 수 있다.

        BigInteger.probablePrime

    2. 호출될 때마다 인스턴스를 새로 생성하지 않아도 된다.
      • 인스턴스가 언제 살아있게 할지 통제할 수 있다.
    3. 반환 타입의 하위 타입 객체를 반환할 수 있다.
      • API를 작게 유지할 수 있게 해주며 엄청난 유연성을 가질 수 있게 해준다.
    4. 입력 매개변수에 따라 매번 다른 클래스의 객체를 반환할 수 있다.
      • 반환 타입의 하위 타입이기만 하면 어떤 클래스의 객체를 반환하든 상관없다.
    5. 정적 팩터리 메서드를 작성하는 시점에는 반환할 객체의 클래스가 존재하지 않아도 된다.
  • 대표적인 정적 팩토리 메소드 이름 | 메서드 이름 | 의미 | 예시 | | :———— | :———————————————– | :————————– | | of | 여러 파라미터를 받아 객체를 생성할 때 사용 | User.of(name, email) | | from | 하나의 다른 객체를 받아 변환/생성할 때 사용 | User.from(UserDto dto) | | valueOf | 변환이나 타입 캐스팅 성격이 강할 때 사용 | Integer.valueOf("123") | | getInstance | 이미 생성된 인스턴스를 반환하거나, 새로운 인스턴스를 반환할 때 사용 | Connection.getInstance() | | newInstance | 매번 새로운 인스턴스를 반환할 때 사용 | Class.newInstance() | | create | 새롭게 무엇인가를 생성할 때 사용 | User.create(name, email) | | build | 복잡한 객체를 조립(Build)해서 반환할 때 사용 (주로 Builder 패턴과 연결) | Order.build(itemList) | | copyOf | 기존 객체의 복사본을 생성할 때 사용 | List.copyOf(originalList) |

    // DTO → Entity 변환
    public static User from(UserRequestDto dto) {
        return new User(dto.getUsername(), dto.getEmail());
    }
    
    // 직접 필드 입력해서 생성
    public static User of(String username, String email) {
        return new User(username, email);
    }
    

Monolithic Arichitecture (모놀로닉 아키텍쳐)

  • 모든 구성 요소(기능)가 하나의 애플리케이션/프로세스 내에서 동작하는 아키텍쳐
  • 일반적으로 하나의 코드베이스, 하나의 빌드 단위, 하나의 배포 단위로 구성됨
  • 예: 사용자 인증, 게시글, 댓글, 결제 등의 기능이 한 프로젝트 안에 모두 들어감
  • 구조 예시
    • [사용자 요청]
          ↓
      [단일 서버 애플리케이션]
      ├─ 사용자 인증 모듈
      ├─ 게시글 처리 모듈
      ├─ 결제 모듈
      └─ DB 처리 모듈
          ↓
      [단일 DB]
      
  • 장점
    • 단순한 개발 : 하나의 코드베이스로 전체 시스템을 빠르게 개발 가능
    • 쉬운 테스트 : 통합된 환경이라 단일 테스트 환경 세팅이 쉬움
    • 쉬운 배포 : 전체 기능이 한 번에 빌드되고 배포됨
    • 직관적인 구조 : 초기에 설계 및 학습이 용이함
  • 단점
    • 규모 확장이 어려움 : 서비스가 커질수록 모듈 간 의존도가 커지고 유지보수가 어려워짐
    • 기능 하나 수정 시 전체 재배포 : 배포 위험도 증가, 릴리즈 속도 저하
    • 장애 전파 가능성 : 하나의 모듈 에러가 전체 애플리케이션에 영향을 줌
    • 기술 스택 제한 : 모듈 별로 다른 언어나 프레임워크 적용이 어려움
  • 언제 사용하면 좋은가?
    • 스타트업이나 초기 프로직트 : 빠르게 MVP(Minimun Viable Product)를 만들고 검증이 필요한 상황
    • 개발 인력이 적거나 복잡도가 낮은 시스템
    • 배포타 운영 환경이 단순한 경우
  • 실제 사용 예시
    • 전통적인 기업 내부 시스템
    • 초기 단계의 웹 서비스 (블로그, 쇼핑몰 등)
  • MSA와 비교 | 구분 | Monolithic | MSA| |——|———–|——–| | 아키텍쳐 | 단일 애플리케이션 | 각 기능이 독립적인 서비스| |개발| 단일 프로젝트 | 서비스 별로 독립 개발| |배포| 전체 배포 | 부분 배포 가능| |확장성| 전체 확장 | 기능 단위 확장| |유지 보수| 복잡해짐 | 모듈화로 유연 | |초기 개발|빠름|상대적으로 복잡|

🦄 느낀 점

  • 정적 팩토리 매서드에 대해 이해가 부족해 이펙티브 자바 책을 서점에서 사서 읽어봤다.
  • 책이 아직 어려워서 공부를 계속 하면서 프로젝트를 진행해야겠다.
    • 좀 더 이해가 되었을 때 블로그에도 정리해보겠다!

🐬 깃블로그 정리

  • []