freezed

5달 전   •   5 min read

By UNIQMUZ
Table of contents

Flutter 개발을 하다 보면 불변 객체와 다양한 유틸리티를 제공하는 모델을 쉽게 생성하고 싶을 때가 많습니다. 이때 유용하게 사용할 수 있는 것이 바로 Freezed 패키지입니다. 이 포스트에서는 freezed 패키지의 주요 기능과 사용 방법, 장점과 단점에 대해 알아보겠습니다.

Freezed란 무엇인가?

freezed는 Flutter에서 불변 객체를 생성하는 데 도움을 주는 패키지입니다. 특히, 데이터 클래스를 작성할 때 반복적으로 작성해야 하는 코드를 간편하게 줄여주고, 타입 안전성, JSON 직렬화, 복사 및 변경 메서드 등을 자동으로 생성해 줍니다.

주요 기능

  • 불변 객체 생성: 객체의 상태를 변경할 수 없도록 만들어 안전한 데이터 구조를 보장합니다.
  • copyWith 메서드: 객체의 특정 필드를 변경하여 새로운 인스턴스를 쉽게 만들 수 있습니다.
  • JSON 직렬화: json_serializable과 함께 사용하여 JSON 데이터를 쉽게 변환할 수 있습니다.
  • Union 타입 지원: 여러 상태를 가지는 클래스, 예를 들어 다양한 상태를 표현하는 sealed class를 작성할 때 유용합니다.

설치하기

freezed 패키지를 사용하기 위해서는 freezedbuild_runner 패키지를 의존성에 추가해야 합니다.

dependencies:
  freezed_annotation: ^2.0.0
  json_annotation: ^4.4.0

dev_dependencies:
  build_runner: ^2.0.0
  freezed: ^2.0.0
  json_serializable: ^6.0.0

설치 후, pub get을 실행하여 패키지를 다운로드합니다.

기본 사용법

freezed 패키지를 사용하여 간단한 모델 클래스를 만들어 보겠습니다. 예를 들어, 사용자 정보를 담고 있는 User 클래스를 작성해 봅니다.

1. 클래스 정의하기

import 'package:freezed_annotation/freezed_annotation.dart';

part 'user.freezed.dart';
part 'user.g.dart';

@freezed
class User with _$User {
  const factory User({
    required String name,
    required int age,
    String? email,
  }) = _User;

  factory User.fromJson(Map<String, dynamic> json) => _$UserFromJson(json);
}

위 코드에서 @freezed 어노테이션을 사용하면 freezed가 자동으로 필요한 메서드와 불변 객체 클래스를 생성해 줍니다. User 클래스에 copyWith 메서드와 toString, ==, hashCode 등의 메서드가 추가됩니다.

2. 코드 생성하기

모델 파일을 정의한 후, build_runner를 사용하여 코드를 생성합니다.

flutter pub run build_runner build

이 명령어를 실행하면 user.freezed.dart 파일과 user.g.dart 파일이 생성되며, 여기에 freezed와 JSON 직렬화에 필요한 코드가 포함됩니다.

Freezed의 기능 알아보기

1. copyWith 메서드

copyWith 메서드를 사용하면 불변 객체의 특정 필드를 변경하여 새로운 인스턴스를 만들 수 있습니다.

void main() {
  final user = User(name: 'Alice', age: 25);
  final updatedUser = user.copyWith(age: 26);

  print(user);        // User(name: Alice, age: 25)
  print(updatedUser); // User(name: Alice, age: 26)
}

2. JSON 직렬화

fromJsontoJson 메서드를 사용하여 JSON 데이터를 쉽게 변환할 수 있습니다.

void main() {
  final json = {'name': 'Alice', 'age': 25};
  final user = User.fromJson(json);

  print(user);            // User(name: Alice, age: 25)
  print(user.toJson());   // {'name': 'Alice', 'age': 25}
}

3. Union 타입 (Sealed Class)

freezed는 Union 타입을 지원하므로, 상태를 구분하는 데 유용합니다. 예를 들어, 네트워크 요청의 결과 상태를 표현할 수 있습니다.

@freezed
class NetworkResult<T> with _$NetworkResult<T> {
  const factory NetworkResult.success(T data) = Success<T>;
  const factory NetworkResult.error(String message) = Error<T>;
}

void main() {
  final successResult = NetworkResult.success('Data loaded');
  final errorResult = NetworkResult.error('Failed to load data');
  
  print(successResult);  // Success(data: Data loaded)
  print(errorResult);    // Error(message: Failed to load data)
}

장점

  • 간결한 코드: boilerplate 코드를 줄여주어 가독성과 유지보수성을 높여줍니다.
  • 강력한 타입 안전성: 불변 객체를 통해 데이터의 안정성과 신뢰성을 보장합니다.
  • 자동화된 JSON 직렬화: json_serializable과 함께 JSON 직렬화/역직렬화를 간편하게 처리할 수 있습니다.

단점

  • 빌드 시간 증가: build_runner를 통해 코드를 생성하므로, 큰 프로젝트에서 빌드 시간이 다소 길어질 수 있습니다.
  • 러닝 커브: Union 타입과 같은 고급 기능을 사용할 때, 초기 학습이 필요할 수 있습니다.
  • 제네릭 타입 제한: 복잡한 제네릭 타입 사용 시 일부 기능이 제한적일 수 있습니다.

마치며

freezed 패키지는 불변 객체를 손쉽게 관리할 수 있도록 도와주는 강력한 도구입니다. copyWith와 JSON 직렬화, Union 타입을 활용하여 데이터 모델을 보다 간결하고 안정적으로 관리할 수 있습니다. 더 많은 기능과 예제는 freezed 공식 문서를 참고하세요.

freezed 패키지를 활용해 더욱 안전하고 강력한 Flutter 코드를 작성해 보세요!

Spread the word

Keep reading