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

모두·2025년 2월 15일

오늘의 포스팅은 정적 팩토리 메서드(Static Factory Method) 패턴에 대하여 글을 작성하고자 한다.

Static Factory Method

  • 정적 팩토리 메서드란 개발자가 구성한 Static Method를 통해서 간접적으로 생성자를 호출하는 객체를 생성하는 디자인 패턴이다.

  • 우리는 지금까지 객체를 인스턴스화 할때 직접적으로 생성자(Constructor)를 호출하여 생성하였는데, 별도의 객체 생성의 역할을 하는 클래스 메서드를 통해 간접적으로 객체 생성을 유도하는 것이다. 그리고 이 정적 메서드를 통칭적으로 정적 팩토리 메서드 패턴이라고 부르는 것이다.

  • 정적 팩토리 메서드는 이름 취지에서도 알 수 있듯이 GOF의 팩토리 메서드Visit Website, 추상 팩토리Visit Website 패턴의 팩토리(Factory) 개념을 따와 심플하게 변형시킨 팩토리 변형 패턴 종류이다.

  • 그런데 왜 생성자를 두고 한단계 거쳐 정적 팩토리 메서드를 통해 객체를 생성하는지에 대한 실용성에 대해 의문을 가질 수 있다(사실 작성자가 의문이 생겼었다 ㅎㅎ).

  • 그런데 실제로 정적 팩토리 메서드는 단순히 생성자의 역할을 대신 이행하는 것 뿐만 아니라 개발자가 좀 더 가독성 좋은 코드를 작성하고 객체 지향적으로 프로그래밍 할 수 있게 도와주기 때문에 실무에서 많이 사용되고 있다는 것을 알게 되었다. 이것은 생성자(Constructor)의 본질적인 문제점을 극복하기 위해서 이기도 한데, 지금부터 왜 정적 팩토리 메서드를 이용해야 되는지에 대한 이유를 적어보려고 한다.

특징

1. 생성 목적에 대한 이름 표현이 가능하다

  • 지금까지 클래스를 설계할 때 여러 타입의 객체를 생성하기 위해, 생성 목적에 따라 생성자를 오버로딩하여 구분하여 사용해왔다. 하지만 문제는 이러한 객체를 new 키워드를 통해 생성자로 생성하려면, 개발자는 해당 생성자의 인자 순서와 내부 구조를 알고 있어야 목적에 맞게 객체를 생성할수가 있다는 번거로움이 있다.

  • 지금까지는 이것이 좋은 방법인 줄 알았기에 이런식으로 사용해왔겠지만 위의 방식은 문제점이 있다는 것을 발견하였다. 코드를 작성할 때 중요한 요소 중 하나는 읽기 쉬운 코드를 작성해야한다는 점이다. 그런 의미에서 new 생성자 방법은 단지 매개변수의 유형과 개수를 제안할 뿐이지 어떠한 역할 표현이나 편의성을 제공하지 않는다. 즉, 생성자로 넘기는 매개변수 만으로는 반환될 객체의 특성을 제대로 표현하기가 어렵다는 것이다.

  • 혼자 진행하는 프로젝트 같은 경우는 본인만 클래스를 이용하기에 큰 문제가 되지 않을 수 있지만 서비스를 만들어서 다른 사람들과 함께 협업을 하는 상황이라면 말이 달라진다. 외부의 다른 개발자 입장에서는 몇번째 인자에 어떤 타입을 할당해야 자신이 원하는 객체를 생성할 수 있는지 정보를 얻으려면 결국 클래스 내부 구조를 뜯어봐야 한다. 이러한 현상은 생성자 이름은 반드시 클래스 이름으로 고정되어 있기 때문에 일어나는 현상이다.

  • 따라서 정적 메서드를 통해 적절한 메서드 네이밍을 해준다면 반환될 객체의 특성을 한번에 유추할 수 있게 된다. 왜냐하면 네이밍을 통해 어떤 값을 이용해 객체를 만들려고 하는지 쉽게 설계 의도를 전달할 수 있기 때문이다. 또한 컴파일 시점에 개발자에게 에러들을 보여주며 실수를 방지 할 수 있는 역할도 한다.

2. 인스턴스에 대해 통제 및 관리가 가능하다

  • 메서드를 통해 한단계 거쳐 간접적으로 객체를 생성하기 때문에, 기본적으로 전반적인 객체 생성 및 통제 관리를 할 수 있게 된다. 즉, 필요에 따라 항상 새로운 객체를 생성해서 반환할 수도 있고, 아니면 객체 하나만 만들어두고 이를 공유하여 재사용하게 하여 불필요한 객체를 생성하는 것을 방지 할 수 있는 것이다.

  • 예시로 Singleton 디자인 패턴을 들 수 있는데, 정적 팩토리 메서드를 사용해 오로지 하나의 객체만 반환하도록 하여 객체를 재사용해 메모리를 아끼도록 유도할 수 있다.

3. 하위 자료형 객체를 반환할 수 있다

  • 클래스의 다형성의 특징을 응용한 정적 팩토리 메서드 특징이다. 메서드 호출을 통해 얻을 객체의 인스턴스를 자유롭게 선택할수 있는 유연성을 갖는 것이다.

4. 객체 생성을 캡슐화 할 수 있다

  • 생성자를 사용하는 경우 외부에 내부 구현을 노출 하는데, 정적 팩토리 메서드는 구현부를 외부로 부터 숨길 수 있어 캡슐화(encapsulation) 및 정보 은닉(information hiding)을 할수 있다는 특징이 있다. 또한 노출하지 않는다는 특징은 정보 은닉성을 가지기도 하지만 동시에 사용하고 있는 구현체를 숨겨 의존성을 제거해주는 장점도 지니고 있다.

네이밍 규칙

  • 정적 팩토리 메서드 와 다른 정적 메서드와 역할을 구분짓기 위해 독자적인 네이밍 컨벤션(Convention)이 존재한다. 각 네이밍의 역할에 대해 알아두고 사용하는 것은 개념을 아는 것만큼 중요하다.

  • from : 하나의 매개 변수를 받아서 객체를 생성

  • of : 여러개의 매개 변수를 받아서 객체를 생성

  • getInstance | instance : 인스턴스를 생성. 이전에 반환했던 것과 같을 수 있음

  • newInstance | create : 항상 새로운 인스턴스를 생성

  • get[OrderType] : 다른 타입의 인스턴스를 생성. 이전에 반환했던 것과 같을 수 있음

  • new[OrderType] : 항상 다른 타입의 새로운 인스턴스를 생성

문제점

  • 생성자보단 정적 팩토리 메서드를 고려해야 하지만, 정적 팩토리 메서드도 단점이 있기 때문에 이를 잘 이해하고 사용하여야 한다. 

1. private 생성자일 경우 상속 불가능

  • 정적 팩토리 메서드로 클래스를 설계를 하면 생성자를 private 접근 제어자로 설정하게 된다. 따라서 정적 팩토리 메서드를 적용하는 경우에는 상속을 이용한 확장이 불가능해진다.

2. API 문서에서의 번거로움

  • 생성자는 하나의 자바 프로그래밍 언어의 스펙이기 때문에 JavaDoc 같은 문서에서 상단에 정의되어 있기 때문에 빠르게 그에 대한 스펙을 검색을 할 수 있다. 반면에 정적 팩토리 메서드는 개발자가 임의로 만든 메서드이기 때문에, 많은 메서드들 중에서 정적 팩토리 역할을 하는 메서드를 찾아 이해해야 한다.

  • 클래스 설계자는 API 문서를 깔끔하게 작성할 필요가 있으며, 정적 팩토리 메서드를 작성할때 네이밍 컨밴션을 지킴으로써 문제점을 극복하기도 한다.

0개의 댓글