Flutter 연구개 발 단계 적 총화 (3) 기본 디자인 모델 MVP

20814 단어 App
위의 내용 을 바탕 으로 우 리 는 간단 한 응용 을 쓸 수 있 지만 페이지 기능 이 증가 함 에 따라 함수 개수, 데이터 와 페이지 의 상호작용 도 이에 따라 증가 할 것 임 을 예견 할 수 있다. 이에 따라 곳곳에 흩 어 진 함수 와 setState 는 코드 를 유지 하기 가 점점 어려워 진다.따라서 적당 한 디자인 모델 을 도입 하여 인터페이스, 데이터 와 논 리 를 결합 시 켜 야 한다.여기 서 MVP 부터 말씀 드 리 겠 습 니 다.
MVP 가 뭐 예요?
인터넷 에 글 이 많아 요.반복 안 할 게 요.
Flutter 의 MVP 실천
여기 서 코드 를 가지 고 말 을 하고 MVP 의 구체 적 인 실천 을 먼저 말 한 다음 에 예 를 들 어 같은 기능 페이지 에서 서로 다른 데이터 소스 를 전환 합 니 다.
1. 기초 MVP 구조 성명
Dart 언어 는 interface 가 없 는 것 같 습 니 다. 여 기 는 abstract class 를 사용 합 니 다.
abstract class IView<T> {
  setPresenter(T presenter);
}
abstract class IPresenter {
  init();
}

2. 구체 적 인 페이지 의 Presenter 와 View 인 터 페 이 스 를 설명 합 니 다.
만약 에 우리 가 한 페이지 를 불 러 올 때 웹 인터페이스 에서 데 이 터 를 가 져 와 표시 하 는 동시에 페이지 는 사용자 의 입력 에 응답 할 수 있 습 니 다. 예 를 들 어 위로 끌 어 올 리 는 것 이 더 많 습 니 다.페이지 행위 차원 에서 우 리 는 다음 과 같은 인 터 페 이 스 를 추상 화 할 수 있다.
abstract class DemoPagePresenter implements IPresenter {
  //             
  void loadData();
  //         
  void loadMore();
}
abstract class DemoPageView implements IView<DemoPagePresenter> {
  //          
  void onLoadSuccess(data);
  //          
  void onLoadError();
  //         
  void onLoadMoreSuccess(data);
  //         
  void onLoadMoreError();
}

이 를 통 해 알 수 있 듯 이 Presenter 는 이벤트 구동 이나 사용자 가 트리거 한 업무 행 위 를 주로 담당 하 는데 페이지 초기 화 시의 로드 데이터 loadData 와 사용자 가 목록 을 끌 어 올 릴 때의 loadMore 를 포함한다.한편, View 는 주로 페이지 논리 처리 후의 결 과 를 보 여 줍 니 다. 예 를 들 어 로드 성공, 실 패 는 각각 무엇 을 보 여 줍 니까?
3. 인터페이스의 구체 적 인 실현
Presenter 와 View 가 모두 성명 을 마 친 후에 구체 적 인 실현 코드 를 시작 할 수 있 습 니 다.여기 서 우 리 는 가짜 코드 로 설명 한다.
1) Presenter 의 구체 적 인 실현 Presenter 는 이벤트 구동 과 사용자 가 촉발 한 후의 논리 에 만 관심 을 가지 고 다른 View 가 어떤 행동 을 취 할 지 결정 하 며 그 자체 가 View 가 어떻게 생 겼 는 지 에 관심 이 없다.이때 의 View 는 Presenter 에 있어 추상 적 인 인터페이스 함수 일 뿐이다.
class DemoPagePresenterImpl implementes DemoPagePresenter {
  //   Presenter    View   ,   View   
  DemoPageView _view;
  // View        Presenter     
  DemoPagePresenterImpl(this._view) {
    _view.setPresenter(this);
  }

  //            ,     Dio,  Sqlite     
  DataRepository _repository;
  int currentPage = 0;

  @override
  init() {
    //          
    _repository = DataRepository();
  }

  //          ,       View   ,   View          
  @override
  loadData() {
    _repository.loadByPage(currentPage).then((data) {
      _view.onLoadSuccess(data);
    }).catchError((error){
      _view.onLoadError();
    });
  }

  //          ,       View   ,   View          
  @override
  loadMore() {
    _repository.loadByPage(++currentPage).then((data) {
      _view.onLoadMoreSuccess(data);
    }).catchError((error){
      _view.onLoadMoreError();
    });
  }
}

2) View 의 구체 적 인 실현 View 는 Flutter 에서 일반적으로 Widget 과 연결 되 어 Widget implements 에 해당 하 는 View 인 터 페 이 스 를 제공 하면 된다.여기 서 View 와 Presenter 의 바 인 딩 작업 을 어느 정도 처리 하고 Presenter 의 init 초기 화 를 완성 해 야 합 니 다.주의: 여기 State 는 View 입 니 다. State 의 Presenter 변 수 는 State 구조 함수 에서 setPresenter 를 통 해 지 정 됩 니 다.이렇게 View 는 Presenter 의 업무 처리 코드 를 언제 출발 하 는 지 에 만 관심 을 가지 지만 구체 적 인 업무 코드 가 어떻게 실현 되 는 지 는 View 에 관심 이 없다.
class DemoPage extends StatefulWidget {
  @override
  _DemoPageState createState() {
    _DemoPageState view = new _DemoPageState();
    //       Presenter,   View      
    DemoPagePresenter presenter = new DemoPagePresenterImpl(view);
    presenter.init();
    return view;
  }
}
class _DemoPageState extends State<DemoPage> implementes DemoPageView {
  DemoPagePresenter _presenter;
  List _resultList = List();  

  @override
  Widget build(BuildContext context) {
    return Column(
      children: <Widget>[
        RaisedButton(
          onPressed: () { _presenter.loadMore(); },
          child: Text('Press to load more')
        ),
        ListView.builder(
          itemCount: _resultList.length,
          builder: (context, index) {
            return Text(_resultList[index]);
          }
        ),
      ]
    );
  }
  
  @overrid
  setPresenter(DemoPagePresenter presenter) {
    _presenter = presenter;
  }
  
  @overrid
  initState() {
    super.initState();
    //           
    _presenter.loadData();
  }

  @override
  onLoadSuccess(data) {
    setState((){
      _resultList = data;
    });
  }
  @override
  onLoadError(){
    print('error!');
  }

  @override
  onLoadMoreSuccess(data) {
    setState((){
      _resultList.addAll(data);
    });
  }
  @override
  onLoadMoreError(){
    print('load more error!');
  }
}

진급: 데이터 원본 전환
수 요 를 바 꾸 는 가장 직접적인 반영 은 바로 개발 환경 과 생산 환경의 전환 이다. 위의 예 는 수요 에 따라 DataRepository 의 서로 다른 실현 유형 을 전환 하면 된다.여기 부분 캡 처.
//            ,     Dio,  Sqlite     
  DataRepository _repository;
  int currentPage = 0;

  @override
  init() {
    //          
    // _repository = DataRepository();
    //      :
    if(appConstants.production) {
      _repository = DataRepositoryProductionImpl();
    } else {
       _repository = DataRepositoryDevelopmentImpl();
    }
  }

좋은 웹페이지 즐겨찾기