Sealed 클래스 (Dart 3)
Coddy Dart 여정의 객체 지향 프로그래밍 섹션에 포함된 레슨 — 110개 중 85번째.
Dart 3는 어떤 클래스가 이를 확장하거나 구현할 수 있는지 제한하는 봉인된 클래스(sealed classes)를 도입했습니다. 클래스를 sealed로 표시하면 동일한 파일에 있는 클래스만 해당 클래스의 직접적인 하위 유형이 될 수 있습니다. 이를 통해 알려진 하위 유형의 닫힌 집합이 생성됩니다.
sealed class Result {}
class Success extends Result {
final String data;
Success(this.data);
}
class Failure extends Result {
final String error;
Failure(this.error);
}봉인된 클래스(sealed classes)의 강력함은 철저한 검사(exhaustiveness checking)에서 나옵니다. 봉인된 타입(sealed type)에 대해 switch 문을 사용할 때, 컴파일러는 가능한 모든 하위 타입을 알고 있으며 각 타입을 처리하도록 보장합니다:
String handleResult(Result result) {
return switch (result) {
Success(data: var d) => 'Got: $d',
Failure(error: var e) => 'Error: $e',
};
// default가 필요하지 않습니다 - 컴파일러가 모든 케이스가 처리되었음을 알고 있습니다!
}
void main() {
var success = Success('Hello');
var failure = Failure('Not found');
print(handleResult(success)); // Got: Hello
print(handleResult(failure)); // Error: Not found
}봉인된 클래스(sealed class)에 새로운 하위 유형(subtype)을 추가하면, 컴파일러는 이를 처리하지 않는 모든 switch 문을 표시합니다. 이로 인해 봉인된 클래스는 상태, 결과 또는 고정된 변형 집합이 있는 모든 시나리오를 모델링하는 데 이상적입니다. 추상 클래스(abstract class)와 달리, 봉인된 클래스는 외부 코드에서 예기치 않은 하위 유형을 추가할 수 없음을 보장합니다.
챌린지
쉬움봉인된 클래스(sealed classes)를 사용하여 네트워크 요청 핸들러를 만들어 봅시다! 네트워크 응답의 다양한 상태를 모델링하는 타입 안전(type-safe) 시스템을 구축하여, 가능한 모든 결과를 적절하게 처리할 수 있도록 할 것입니다.
코드를 두 개의 파일로 구성합니다:
response.dart: 네트워크 응답의 모든 가능한 상태를 나타내는 봉인된 클래스 계층 구조를 만듭니다:- 모든 응답 유형의 기반이 되는
NetworkResponse라는 이름의 봉인된 클래스(sealed class) String message필드(예: "Fetching data...")를 가지며NetworkResponse를 확장하는Loading클래스String data필드와int statusCode필드를 가지며NetworkResponse를 확장하는Success클래스String errorMessage필드와int errorCode필드를 가지며NetworkResponse를 확장하는Error클래스
- 모든 응답 유형의 기반이 되는
main.dart: 응답 파일을 임포트하고 switch 표현식을 사용하여 모든 응답 유형을 처리하는 함수를 만듭니다:String을 반환하는handleResponse(NetworkResponse response)함수를 만듭니다.- 패턴 매칭이 포함된 switch 표현식을 사용하여 각 케이스를 처리합니다:
Loading의 경우:Status: [message]를 반환합니다.Success의 경우:Success ([statusCode]): [data]를 반환합니다.Error의 경우:Error ([errorCode]): [errorMessage]를 반환합니다.
- 세 개의 응답 인스턴스를 생성하고 각각을 처리한 결과를 출력합니다:
- 메시지가
Please wait...인Loading인스턴스 - 데이터가
User profile loaded이고 상태 코드가200인Success인스턴스 - 에러 메시지가
Not found이고 에러 코드가404인Error인스턴스
- 메시지가
봉인된 클래스의 장점은 컴파일러가 모든 가능한 응답 유형을 처리하도록 보장한다는 것입니다. 따라서 default 케이스가 필요하지 않습니다!
예상 출력:
Status: Please wait...
Success (200): User profile loaded
Error (404): Not found직접 해보기
import 'response.dart';
// TODO: handleResponse(NetworkResponse response) 함수 만들기
// String을 반환하는 함수
// 패턴 매칭이 포함된 switch 표현식을 사용하여 각 케이스를 처리하세요:
// - Loading의 경우: "Status: [message]" 반환
// - Success의 경우: "Success ([statusCode]): [data]" 반환
// - Error의 경우: "Error ([errorCode]): [errorMessage]" 반환
void main() {
// TODO: message가 "Please wait..."인 Loading 인스턴스 생성
// TODO: data가 "User profile loaded"이고 status code가 200인 Success 인스턴스 생성
// TODO: error message가 "Not found"이고 error code가 404인 Error 인스턴스 생성
// TODO: 각 응답을 처리한 결과 출력
}
이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.