Freezed 패키지

개발 기록·2024년 2월 25일

Flutter

목록 보기
5/18
post-thumbnail

Freezed 라이브러리란?

데이터 클래스에서 흔히 필요한 기능을 한번에 제공해주는 라이브러리로, Json Serializable 보다 다양하고 많은 편의성을 제공해줌

라이브러리 설치

dependencies:
  freezed_annotation:

dev_dependencies:
  build_runner:
  freezed:

Freezed는 annotation 기능을 사용해서 Code Generation 기능을 실행함
일반적으로 property를 선언시, 내부 변수를 미리 선언한 후 constructor(생성자)로 입력된 변수들을 클래스에서 사용함
하지만 Freezed는 factory constructor을 사용하기 때문에 내부에 변수를 따로 정의하지 않아도 됨. 자동으로 mixin을 통해 Code Generation 되기 때문에 속도가 더름

factory constructor이란?

각 클래스에서 하나의 인스턴스만 생성하는 싱글톤 패턴으로, 기 생성 인스턴스가 아니라면 새롭게 생성하고, 기 생성 인스턴스가 존재한다면 기존 것을 반환하는 것. 즉 훨씬 효율 적임

코드예시)

class TodoModel with _$TodoModel {
  const factory TodoModel({
    required String title,
    required String description,
    required int isCompleted,
    required int id,
    required String dueDate,
    required String createdAt,
    required String updatedAt,
  }) = _TodoModel;
최초에 생성한 인스턴스를 _TodoModel에 저장하고, 이후 인스턴스 생성이 발생하면 기 등록한 _TodoModel 반환 (공장보단 창고의 의미)


  factory TodoModel.fromJson(Map<String, dynamic> json) =>
      _$TodoModelFromJson(json);
      //fromJson 및 toJson 기능 사용시 part '파일이름.g.dart' 추가하여 사용

Code Generation 실행코드

flutter pub run build_runner build

해당 코드 실행시 freezed 및 g 파일 자동 업뎃됨

Freezed 여러 기능 (예시 코드)

1. constructor 및 property 자동 생성

final person1 = Person(id: 1, name: 'Code Factory', age: 52);

// 1
print(person1.id);

// Code factory
print(person2.name);

2. toString 및 toJson

final person1 = Person(id: 1, name: 'Code Factory', age: 52);

// Person(id: 1, name: Code Factory, age: 52)
print(person1);

// {id: 1, name: Code Factory, age: 52}
print(person1.toJson());

일반적으로 dart에서 인스턴스에 toString() 함수 실행시키면 Instance of {클래스} 라는 아쥬 짜증나는 결과가 리턴된다.
하지만 freezed에서는 그런 것 없이 메소드가 자동으로 override 되어서 디버깅 된다는 것 !

3. == 및 haseCode override

final person1 = Person(id: 1, name: 'Code Factory', age: 52);
final person2 = Person(id: 1, name: 'Code Factory', age: 52);

// true
print(person1 == person2);

== 함수 및 hasCode 함수 또한 자동 override 되어서 비교 가능

4. assert


class Person with _$Person {
  ('name.length < 5', '이름은 5자 이하만 입력 가능합니다.')
  factory Person({
    required int id,
    required String name,
    required int age,
  }) = _Person;

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

// 에러 -> 이름은 5자 이하만 입력 가능합니다.
final person1 = Person(id: 1, name: 'Code Factory', age: 52);

위 코드 처럼 Assert 키워드를 통해 조건을 달고, 조건을 만족하지 못했을 시, 에러 문구가 반환되도록 설정이 가능함.
String 값으로만 코드를 작성해야하는 한계 존재.
factory 위에 여러개의 Assert로 복수 조건 설정 가능.

5. 커스텀 메소드 및 getter 작성


class Person with _$Person {
  factory Person({
    required int id,
    required String name,
    required int age,
  }) = _Person;

  factory Person.fromJson(Map<String, dynamic> json) => _$PersonFromJson(json);

  // 메소드나 custom getter 작성시 필수로 추가
  Person._();
  
  get nameLength => name.length;

메소드나 getter 작성시 필수로 추가 해줘야함
(setter는 설정 불가)

참고
https://blog.codefactory.ai/flutter/freezed/

0개의 댓글