Menu
Coddy logo textTech

팩토리 생성자

Coddy Dart 여정의 객체 지향 프로그래밍 섹션에 포함된 레슨 — 110개 중 14번째.

팩토리 생성자(factory constructor)는 항상 새로운 인스턴스를 생성하지는 않는 특별한 생성자입니다. 일반 생성자와 달리, 팩토리 생성자는 기존 인스턴스, 하위 타입 또는 (null 허용인 경우) null을 반환할 수 있습니다. factory 키워드를 사용하여 선언합니다.

class Logger {
  static final Logger _instance = Logger._internal();
  
  // 비공개 명명 생성자
  Logger._internal();
  
  // 팩토리 생성자
  factory Logger() {
    return _instance;
  }
}

Logger log1 = Logger();
Logger log2 = Logger();
print(identical(log1, log2)); // true

이 예제에서 팩토리 생성자는 항상 동일한 인스턴스를 반환합니다. Logger()를 얼마나 많이 호출하든 관계없이 동일한 객체를 얻게 됩니다. 이 패턴은 싱글톤을 구현하는 데 흔히 사용됩니다.

팩토리 생성자는 일반 생성자와 중요한 차이점이 있습니다. 팩토리 생성자는 새로운 인스턴스를 전혀 생성하지 않을 수도 있기 때문에 this에 접근할 수 없습니다. 대신, 반드시 명시적으로 객체를 반환해야 합니다:

class Shape {
  factory Shape(String type) {
    if (type == 'circle') return Circle();
    if (type == 'square') return Square();
    return Rectangle();
  }
}

class Circle extends Shape { Circle() : super._(); }
class Square extends Shape { Square() : super._(); }
class Rectangle extends Shape { Rectangle() : super._(); }

팩토리 생성자는 캐시된 객체를 반환하거나, 객체 풀을 구현하거나, 입력 매개변수에 따라 어떤 하위 타입을 인스턴스화할지 결정하는 것과 같이 인스턴스 생성에 대한 제어가 필요할 때 유용합니다.

challenge icon

챌린지

쉬움

단순한 문자열 입력을 기반으로 다양한 유형의 알림을 생성하기 위해 팩토리 생성자를 사용하는 알림 시스템을 구축해 보겠습니다.

코드를 정리하기 위해 두 개의 파일을 생성합니다:

  • notification.dart: 모든 알림 유형의 기반이 되는 Notification 클래스를 정의합니다. 클래스에는 다음이 포함되어야 합니다:
    • String message 필드
    • 메시지를 초기화하는 프라이빗 명명된 생성자 Notification._internal
    • type 파라미터에 따라 서로 다른 알림 서브타입을 반환하는 팩토리 생성자 Notification(String type, String message):
      • type이 'email'이면, EmailNotification을 반환합니다.
      • type이 'sms'이면, SMSNotification을 반환합니다.
      • 그 외의 경우에는 PushNotification을 반환합니다.
    • Sending: [message]를 출력하는 send() 메서드

같은 파일에 Notification을 상속받는 세 개의 서브클래스를 생성합니다:

  • EmailNotification: send()를 오버라이드하여 Email: [message]를 출력합니다.
  • SMSNotification: send()를 오버라이드하여 SMS: [message]를 출력합니다.
  • PushNotification: send()를 오버라이드하여 Push: [message]를 출력합니다.

각 서브클래스는 message를 인자로 받아 super._internal(message)를 사용하여 부모 클래스에 전달하는 생성자가 필요합니다.

  • main.dart: 알림 클래스를 임포트하고 팩토리 생성자를 사용하여 세 개의 알림을 생성합니다:
    • 메시지가 'Welcome!'인 이메일 알림
    • 메시지가 'Your code is 1234'인 SMS 알림
    • 메시지가 'New update available'인 푸시 알림
    위에 나열된 순서대로 각 알림에 대해 send()를 호출합니다.

예상 출력:

Email: Welcome!
SMS: Your code is 1234
Push: New update available

치트 시트

팩토리 생성자(factory constructor)factory 키워드로 선언되는 특별한 생성자로, 항상 새로운 인스턴스를 생성하지는 않습니다. 일반 생성자와 달리, 기존 인스턴스나 서브타입(subtype), 또는 null을 반환할 수 있습니다.

팩토리 생성자는 this에 접근할 수 없으며, 반드시 객체를 명시적으로 반환해야 합니다.

싱글톤 패턴 예시:

class Logger {
  static final Logger _instance = Logger._internal();
  
  Logger._internal(); // Private named constructor
  
  factory Logger() {
    return _instance; // Always returns same instance
  }
}

Logger log1 = Logger();
Logger log2 = Logger();
print(identical(log1, log2)); // true

다양한 서브타입 반환하기:

class Shape {
  factory Shape(String type) {
    if (type == 'circle') return Circle();
    if (type == 'square') return Square();
    return Rectangle();
  }
}

class Circle extends Shape { Circle() : super._(); }
class Square extends Shape { Square() : super._(); }
class Rectangle extends Shape { Rectangle() : super._(); }

팩토리 생성자는 캐시된 객체를 반환하거나, 객체 풀(object pool)을 구현하거나, 입력 매개변수에 따라 어떤 서브타입을 인스턴스화할지 결정하는 등 인스턴스 생성을 제어하는 데 유용합니다.

직접 해보기

import 'notification.dart';

void main() {
  // TODO: 'Welcome!' 메시지로 이메일 알림 생성
  
  // TODO: 'Your code is 1234' 메시지로 SMS 알림 생성
  
  // TODO: 'New update available' 메시지로 푸시 알림 생성
  
  // TODO: 각 알림에 대해 순서대로 send() 호출
}
quiz icon실력 점검

이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.

객체 지향 프로그래밍의 모든 레슨