인프런 커뮤니티 질문&답변

aoddydrl119님의 프로필 이미지
aoddydrl119

작성한 질문수

Flutter 중급 2편 - 실전 앱 개발 - 미국 주식 앱 (with 클린 아키텍처)

개념 - 왜 클린아키텍처인가?

강의 예시에 대한 답변이 궁금합니다.

작성

·

285

·

수정됨

0

4:20초에서 '예) 로그인 작업시 얻은 Token 정보를 LoginViewModel에서 가지고 있다.~~' 라는 질문에 대한 답변이

Token 정보가 필요한 스크린들에서 하나의 ViewModel을 공유하라는 것이 맞을까요?

답변 1

0

오준석님의 프로필 이미지
오준석
지식공유자

네. ViewModel을 공유하는 방법도 있으나

이러저러한 이유로 추천하는 방법은 아니다 라고 다다음 장표에서 설명합니다.

aoddydrl119님의 프로필 이미지
aoddydrl119
질문자

그렇다면 UseCase에 데이터(token 등)를 가지고 있고 그것을 각 화면의 ViewModel에서 사용하라는 말씀이신가요?

 

오준석님의 프로필 이미지
오준석
지식공유자

궁극적으로는 UseCase가 token을 제공해 주는데 Token을 제공하는 Repository를 사용해야 할 것이고 Repository는 GetIt 과 같은 서비스 로케이터로부터 Token 정보를 제공받는 형태가 되면 좋겠네요.

aoddydrl119님의 프로필 이미지
aoddydrl119
질문자

제가 이해를 잘 하지 못해 예시로 질문 다시 드리겠습니다.

만약 A화면과 B화면에서 동일한 회원의 정보를 필요로 할 때,

AViewModel과 BViewModel에 각각 회원 정보를 담을 변수가 필요할 것 같습니다.(예시에서는 memberInfo입니다.)

class AViewModel with ChangeNotifier {
// BViewModel도 동일

  final MemberUseCases _memberUseCases;

  Map<String, dynamic> memberInfo = {};

  MyPageViewModel(this._memberUseCases);

  Future<void> getMyInfo() async {
    final result = await _memberUseCases.getMemberInfo();
    result.when(
      success: (memberData) {
        memberInfo = memberData;
        notifyListeners();
      },
      error: (e) {
        log(e);
      },
    );
  }
}

 

AViewModel과 BViewModel은 같은 UseCases인 MemberUserCases를 주입 받을 것입니다.

UseCases에서는 회원의 정보를 가져오는 GetMemberInfoUseCase가 있을 것입니다.

class MemberUseCases {
  final GetMemberInfoUseCase getMemberInfo;
  final RemoveMemberInfoUseCase removeMemberInfo;
  ~~..

  MemberUseCases(this.joinMember, this.getMemberInfo, ~~..);
}

class GetMemberInfoUseCase {
  final MemberRepository repository;

  GetMemberInfoUseCase(this.repository);

  Future<Result<Map<String, dynamic>>> call() async {
    return await repository.getMyInfo();
     // -> 외부 API 통신이 필요하다.
  }
}

 

제 질문은 다음과 같습니다.

AViewModel과 BViewModel에서 같은 데이터를 필요로 할 때(예시에서는 회원의 정보), 주입된 UseCase를 통해 각 뷰모델에 전달받을 수 있지만 UseCase를 쓸때마다 외부 API 통신을 하게 됩니다.

그래서 제가 처음에 여쭤봤던
'그렇다면 UseCase에 데이터(token 등)를 가지고 있고 그것을 각 화면의 ViewModel에서 사용하라는 말씀이신가요?'의 질문은
Repository까지 가지 않고 통신하지 않기 위함이었습니다.

통신을 하지 않고 한 번 가져온 데이터를 메모리 상에 계속 유지하려고 할 때, 뷰모델을 분리하는 방식이 궁금합니다.

'예) 로그인 작업시 얻은 Token 정보를 LoginViewModel에서 가지고 있다.~~'에서도 한 번 가져온 Token 값을 어떻게 유지하여 다른 화면에 공유하는지와 같은 맥락인 것 같습니다.

 

물론 AViewModel에서 얻은 데이터를 Screen 단에서 BViewModel에 전달해 줄 수 있지만 이는 UseCase를 사용하는 의미가 없다고 생각이 듭니다.

그래서 AViewModel을 A화면과 B화면에 선언하여 사용하는 방식(분리하지 않고 하나의 뷰모델을 여러 화면에 사용)으로 사용하고 있었습니다.

 

긴 글이라 죄송스럽지만 양해를 구하고 질문드립니다!

 

오준석님의 프로필 이미지
오준석
지식공유자

구조는 잘 구성하셨습니다.

UseCase를 쓸 때마다 외부 API 통신을 할 지 말지를 UseCase 내에서 로직을 추가하여 조절하실 수 있습니다.

지금 코드는 단순히 Repository를 통해서 값을 가지고 오는 코드만 있습니다.

예를 들어 한번 가져온 Token 을 별도의 Local 저장소에 저장을 하고, 다음 번 요청시에 Local 저장소에 저장한 Token을 가져오는 식으로 UseCase 로직을 수정하시면 되겠습니다.

즉, GetMemberInfoUseCase 가 MemberRepository와 LocalStorageRepository 를 생성자로 받고 조합하여 Token을 돌려주도록 수정하면 될 것 같습니다.

이해가 안 되는 내용이 있다면 또 질문해 주세요.

aoddydrl119님의 프로필 이미지
aoddydrl119
질문자

이해했습니다!

좋은 답변 감사드립니다.

aoddydrl119님의 프로필 이미지
aoddydrl119

작성한 질문수

질문하기