승상의 코딩 블로그

[Flutter] 불변객체와 내부 속성을 쉽게 만들어주는 freezed 패키지 본문

Flutter (플러터)

[Flutter] 불변객체와 내부 속성을 쉽게 만들어주는 freezed 패키지

양승상 2023. 8. 22. 23:05
반응형

모델 클래스를 정의하는 것은 귀찮은 일이다. Json 을 받는 코드, 객체의 특정 속성만 변경하여 새로운 객체를 반환하는 코드 등 ...

클래스가 많아질수록 자동화하지 않으면 시간이 많이 걸릴 뿐 아니라 에러가 발생할 확률이 높아진다.

 

다행히 플러터에는 이러한 문제를 해결하기 위한 코드 제너레이션(code generation) 패키지가 존재한다. 코드 제너레이션은 코드의 일부를 자동으로 만들어주는 기술을 의미한다. 코드 제너레이션을 통해 반복된 코드를 자동으로 생성할 수 있다.

https://pub.dev/packages/freezed

 

freezed | Dart Package

Code generation for immutable classes that has a simple syntax/API without compromising on the features.

pub.dev

freezed 패키지 설명에 따르면 아래 사진처럼 코드 양을 엄청나게 줄일 수 있다고 한다.

freezed 사용전 (좌) freezed 사용후 (우) 출처 : https://pub.dev/packages/freezed

설치

> flutter pub add freezed_annotation
> flutter pub add --dev build_runner
> flutter pub add --dev freezed
# Jsonserialize 처럼 fromJson/toJson 을 사용하고 싶다면 아래 명령을 추가로 실행한다.
> flutter pub add json_annotation
> flutter pub add --dev json_serializable

freezed 는 code generator 이기 때문에 --dev 로 개발환경에만 설치한다.

Code Generator 를 실행할 코드를 작성한 이후 아래의 명령어를 입력하면 코드가 생성된다.

> flutter pub run build_runner build

모델 코드 작성

import 'package:freezed_annotation/freezed_annotation.dart';

// part 뒤의 파일들은 build runner 로 생성될 파일들이다. 
part 'review.freezed.dart';
part 'review.g.dart'; // fromJson 을 사용하고 싶다면 추가로 기입한다.

@freezed
class Review with _$Review {
  const factory Review({
    required String user,
    required String review,
  }) = _Review;

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

_$ 는 freezed 에서 코드 생성을 위해 사용하는 네이밍 규칙이다.

> flutter pub run build_runner build

build runner 를 수행하면 아래와 같이 코드가 생성된다.

builder_runner 사용 후 코드 생성됨

코드 생성으로 만들어지는 파일들은 수정하는 경우가 거의 없으므로 기본 파일의 하위항목으로 숨겨버리자.

숨기는 방법은 아래 포스팅을 참고하여 설정하자.

2023.08.21 - [Flutter (플러터)] - [Flutter] vs code 에서 code generation 파일 그룹핑하기(File Nesting)

 

[Flutter] vs code 에서 code generation 파일 그룹핑하기(File Nesting)

플러터의 많은 라이브러리들이 코드 제너레이션(code generation)을 제공한다. 코드 제너레이션은 코드의 일부를 자동으로 만들어주는 기술을 의미한다. 코드 제너레이션을 통해 반복된 코드를 자

seungsang.tistory.com

특징

freezed 를 사용하면 여러 이점이 있다. 기능이 많기 때문에 대표적인 기능만 살펴보자.

  1. 객체가 불변이다.
    객체가 불변일 경우 코드 중간에 데이터 변경으로 인한 사이드 이펙트를 막아준다. 그 외에도 다양한 이유가 많지만 나는 이 장점을 가장 많이 느꼇다.

객체의 속성을 변경하면 에러 알림이 뜬다.

  1. 객체의 일부 속성을 변경하여 복사하기 쉽다.
    객체가 불변이기 때문에 값을 복사하기 위한 함수가 필요하다. freezed 에서는 copyWith 함수를 통해 지원한다.
    copyWith 로 전달하지 않은 인자의 값은 복사하는 객체에 전달된다.

copyWith 를 통해 원하는 값만 변경한 새로운 객체를 얻을 수 있다.

  1. 객체 속성을 통한 비교가 간편해진다.
    원래라면 동일한 클래스더라도 서로 다른 객체이기 때문에 비교하면 일치하지 않는다고 뜬다.
    그래서 원래는 두 객체를 비교하는 함수를 재정의 해줘야 했지만, freezed 를 사용하면 이에 대한 코드를 대신 생성해준다.
// freezed 를 사용하지 않은 일반 클래스를 생성함
class Review2 { 
  Review2({
    required String user,
    required String review,
  });
}

void main() {
  var review = Review2(user: 'seungsang', review: 'Very Nice!');
  var review2 = Review2(user: 'seungsang', review: 'Very Nice!');

  print(review == review2); // false : freezed 를 사용하지 않은 클래스

  var review_freezed1 = Review(user: 'seungsang', review: 'Very Nice!');
  var review_freezed2 = Review(user: 'seungsang', review: 'Very Nice!');

  print(review_freezed1 == review_freezed2); // true : freezed 를 사용한 클래스
}
  1. FromJson/ToJson 을 사용할 수 있다. (json_serialiable 패키지를 활용해서 만들어진다)
    아래 build runner 를 통해 생성된 코드이다.
    FromJson 를 살펴보자. json[클래스 속성] 값을 사용해서 객체를 생성한다.

Code Generation 된 코드 review.g.dart

 

 

추가로, Freezed 에서는 Factory Constructor 를 활용한 when 함수도 제공해준다.

Constructor 에 각 함수의 프로토타입을 엮어준다. 자세한 것은 아래링크에서 확인해보자.

2023.08.24 - [Flutter (플러터)] - [Flutter] Named Constructor, Factory Constructor (Freezed 패키지 when 함수)

 

[Flutter] Named Constructor, Factory Constructor (Freezed 패키지 when 함수)

class Person { late String name; late int age; // Unnamed Constructor 는 하나만 생성 가능하다. Person(this.name, this.age); // Named Constructor Person.fromJson(Map data) { name = data['name']; age = data['age']; } } Unnamed/Named Constructor C++

seungsang.tistory.com

 

반응형
Comments