본문 바로가기
모바일

Flutter 데이터 모델링 할 때 Freezed를 쓰는 이유에 대하여

반응형

Flutter 개발자로 일하고 있지만 여러 프로젝트를 쳐내는 것에 급급하여

제대로 공부하는 것은 애써 외면하고 있었습니다만

프로젝트를 하면서 알게 된 것들을 포스팅함으로써

공부해보려고 합니다!

고럼 스타뚜-!

 

 

 

 

 


 

알고 가면 좋은 immutable 개념

일단 시작하기 앞서 알고가면 좋을 immutable 개념을 볼까요?

immutable은 의미 그대로 불변 이라는 뜻입니다. 이에 상반되는 mutable(변하기 쉬운)도 있습니다.

 

var music = 'ismylife';
print(music);



여기서 music 변수는 'ismylife' 라는 값을 갖고 있습니다.

print로 변수값을 찍어본다면 당연히 ismylife 값이 나옵니다.

 

music = 'islove';
print(music);

 

이다음music 값을 ' islove' 를 넣고 다시 찍어본다면 변경된 값이 나옵니다.

변수값이 잘 바뀌는 것처럼 생각할 수 있습니다.

하지만 music 변수는 immutable 변수입니다. String type은 immutable 변수예요.

 

그렇지만 분명 잘 바뀌잖아.! 라고 생각할 수 있습니다.

왜 그럴까요? 이 개념은 조금 딥하게 들어가야 합니다.

컴퓨터 속으로...

 

 

 

컴퓨터에서 변수를 저장할 때 메모리 주소를 할당합니다.

music 변수를 선언하고 값을 넣었을 때 메모리 주소가 할당되어 그 공간에 저장이 됩니다.

 

처음 music변수는 10101012 라는 메모리 위치에 ' islove'이라는 값을 가지고 있습니다.

그치만 이건 immutable한 변수라고 했죠?

music 변수를 'islove'로 변경했을 때 같은 메모리 위치에 저장되는 것이 아닌

다른 메모리 주소 값에 저장되는 것입니다.

 

 

 

이해를 돕기 위해 초라한 시각자료를 첨부해 봤습니다.

처음 변수 생성해서 값 저장할 경우                                            변수에 다른 값을 넣어서 저장할 경우

 

그림과 같이 music이라는 변수명은 같지만 다른 메모리 위치를 가지게 됩니다.

주소 값만 바뀔 뿐 기존 저장된 메모리 위치에 있는 값은 변하지 않습니다.

 

그렇다면 값을 변경했을 경우 기존에 있는 메모리 위치는 어떻게 되는 것인가!?

Dart의 Garbage Collector 가 해결해 줍니다. 간단 해-결

 

 

설명이 길었는데 각 데이터를 변경 시

immutable: 메모리 위치도 변경해서 저장한다.

mutable: 메모리 위치를 변경하지 않고 데이터를 변경할 수 있다.

요런 차이가 있네요.

 

 

 


데이터 모델링시 Freezed를 사용해야 하는 이유

❗우리는 왜 데이터 모델링 할 때 Freezed를 사용해야 할까요?

 

 

 

본론으로 넘어가면 데이터 모델링시 Freezed를 사용하는 이유..! 장점이 많아서..

물론 다양한 장점이 많겠지만 제가 생각하는 큰 장점은 데이터를 비교할 때라고 생각합니다.

void main() {
  var string_one = 'Teststring!';
  var string_two = string_one;
  print(string_one == string_two);
  
  Music vocal_one = Music(id: 1, genre:'rock');
  Music vocal_two = Music(id: 1, genre:'rock');
  print(vocal_one == vocal_two);
}

class Music {
  final int id;
  final String genre;

  Music({
    required this.id,
    required this.genre,
  });
}

 

위 코드를 실행시키면 들어있는 값이 다 같으니까 두 가지 경우 다  true가 나올 거 같지 않나요?

그렇지만 결과는 그렇지 않습니다.

결과값

 

 

string_one과 string_two는 동일한 텍스트를 포함하니까 true가 나온다는 건 알겠는데...

Music 클래스의 객체인 vocal_one 변수와 vocal_two 변수는 들어있는 값이 같은데도 왜 false가 나올까요?

 

vocal_one 변수와 vocal_two 변수는 동일한 Music 클래스의 속성을 같고 있지만

메모리의 주소가 다르기 때문에 이런 결과가 나옵니다.

 

 

프로젝트를 진행하다 보면 데이터를 비교해야 하는 상황이 빈번한데

이점은 굉장히 어렵다 말이죠.. 

그래도 뭐... 해결할 방법은 있습니다.

class Music {
  final int id;
  final String genre;

  Music({required this.id,required this.genre});
  
  @override
  bool operator ==(Object other) =>
      identical(this, other) ||
      other is Music && runtimeType == other.runtimeType && id == other.id && genre == other.genre;

  @override
  int get hashCode => id.hashCode ^ type.hashCode;
}

 

Music 클래스 안에 operator와 hashCode 함수를 넣어주면 됩니다.

허나.. 이걸 매번 할 수 없잖아요?ㅎ

클래스 안에 정의해야 하는 값이 많아진다면..? 

 

 

또 다른 해결할 방법이 있습니다. 그것은 Equatable 패키지를 사용하는 것

pub add 로 패키지 추가하고

import 'package:equatable/equatable.dart';

class Music extends Equatable {
  final int id;
  final String genre;

  MusicEqu({required this.id, required this.genre});

  @override
  List<Object?> get props => [id, genre];
}

Music 모델에 Equatable을 상속해 줍니다.

그러면 객체 비교가 가능해요.

 

 

하지만 Freezed는 Equatable 를 포함한 json_serializable과 혼합하여 쓸 수 있고,

toString, copyWith.. 등 편리한 기능도 추가로 제공해 준다는 점,

자동으로 파일을 생성해 주므로 코드가 간결해진다는 점,

이런 다양한 이유들이 있기에 Freezed를 사용해서 모델링해야 한다고 생각했습니다.

 

 

 

flutter pub run build_runner watch 를 실행해주면 .freezed 파일이 생겨요.

안에를 뜯어보면! 우리가 필요로 하는 operator, hashCode가 들어있습니다!

추가로 toString이나 copyWith도 확인 가능

 

 

 

 

빠르게 결론

저는 이걸 알게 된 게  너무 좋았어서 게시글로 써야겠다 싶더라고요.

뭐든 쓰는 이유에 대해 알고 쓰면 좋잖아요~

데이터 모델링에서 freezed를 쓰는 이유가 이거군? 하는 생각이 들게 하는 게시글이었으면 좋겠습니다.

 

 

 

감사합니다!

반응형