의존성 문제 해결 방법

luneah·2022년 10월 13일
0

Flutter

목록 보기
26/29
post-thumbnail

의존성이 결합된 구조 → 의존성을 제거한 더 나은 대안

의존성을 제거하는 방법

Model
1. 데이터를 제공하는 공통 인터페이스를 제공

abstract class Repository {
  Future<List<Chat>> getChatList();
}

구현체가 여러가지일 경우를 대비해 추상 클래스로 만든다. (구현체가 여러가지가 아닌 경우에는 추상 클래스를 꼭 만들 필요는 없다.)
2. 구체화한 객체를 구현

class LocalRepository extends Repository {
  
  Future<List<Chat>> getChatList() async {
    Future.delayed(Duration(seconds: 1));

    return [
      Chat('홍길동', null, 'hello world', 100234234234, 'aaa@aaa.com'),
      Chat('홍길동', null, 'hello world 2hello world 2hello world 2hello world', 100234234234, 'aaa@aaa.com'),
      Chat('한석봉', null, 'hello world 3', 100234234234, 'bbb@aaa.com'),
    ];
  }
}
  1. 추가적으로 필요한 모델을 구현할 수 있음
class FirebaseRepository extends Repository {
  
  Future<List<Chat>> getChatList() {
    // TODO: implement getChatList
    throw UnimplementedError();
  }
}

ViewModel
1. View 측에서 사용할 기능과 데이터 정의

class ChatViewModel extends ChangeNotifier {
  final Repository<Chat> repository = FakeRepository();

  List<Chat> _chatList = [];
  List<Chat> get chatList => _chatList;

  bool _isLoading = false;
  get isLoading => _isLoading;

  void fetch() {
    _isLoading = true;
    repository.getAll().then((value) {
      _chatList = value;
      _isLoading = false;
      notifyListeners();
    });
  }

  void pushMessage(String email, String text, int time) {
    repository.add(Chat(
      '홍길동', 
      'https://asd.fdsda.com/asd/adfWEazsdasdQEas', 
      text,
      time,
      email,
    )).whenComplete(() {
       notifyListeners(); 
    });
  }
}

ChangeNotifier를 상속하고 데이터가 변경되면(UI를 갱신해야 할 때마다) notifyListeners()를 호출

  • 전달할 객체가 많을 때는 MultiProvider 사용 (애초에 이렇게 쓰는 것이 편함)
void main() {
  runApp(
    MultuProvider(
      providers: [
        ChangeNotifierProvider.value(value: ChatViewModel()),
      ],
      child: MyApp(),
    ),
  );
}
  1. View 측에서는 provider 라이브러리를 활용하여 ViewModel을 얻음

Widget build(BuildContext context) {
  final viewModel = context.watch<ChatViewModel>();
  
  return Scaffold(
    appBar: AppBar(
      title: Text(''),
  • context.watch<> : 지속 관찰, 변경 시 통지를 받음 (UI 갱신됨)
  • context.read<> : 일회성 접근

ViewModel과 Model의 의존성 문제

가장 이상적인 형태 = Model, View, ViewModel이 모두 독립적인 형태

비즈니스 로직 수정시 - Model 수정
UI 수정시 - View 수정
기능 수정시 ViewModel 수정
⇒ ViewModel은 Model의 구체적인 내용을 알 필요가 없다.

해결 방법

  1. 생성자를 통해 추상화 된 객체 타입을 받는다.

  2. 생성자를 통해 인스턴스를 전달

    ⇒ Model 교체가 편해짐

지켜야 할 것

  1. ViewModel은 UI에 필요한 로직이나 데이터를 가진다.
  2. UI는 화면을 그리는 것 이외의 데이터나 로직을 가지지 않는다.
  3. 데이터가 변경되어도 ViewModel의 코드를 수정하지 않아도 되도록 한다.
profile
하늘이의 개발 일기

0개의 댓글