팩토리 생성자
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._(); }팩토리 생성자는 캐시된 객체를 반환하거나, 객체 풀을 구현하거나, 입력 매개변수에 따라 어떤 하위 타입을 인스턴스화할지 결정하는 것과 같이 인스턴스 생성에 대한 제어가 필요할 때 유용합니다.
챌린지
쉬움단순한 문자열 입력을 기반으로 다양한 유형의 알림을 생성하기 위해 팩토리 생성자를 사용하는 알림 시스템을 구축해 보겠습니다.
코드를 정리하기 위해 두 개의 파일을 생성합니다:
notification.dart: 모든 알림 유형의 기반이 되는Notification클래스를 정의합니다. 클래스에는 다음이 포함되어야 합니다:String message필드- 메시지를 초기화하는 프라이빗 명명된 생성자
Notification._internal type파라미터에 따라 서로 다른 알림 서브타입을 반환하는 팩토리 생성자Notification(String type, String message):- type이
'email'이면,EmailNotification을 반환합니다. - type이
'sms'이면,SMSNotification을 반환합니다. - 그 외의 경우에는
PushNotification을 반환합니다.
- type이
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() 호출
}
이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.