MVC의 바자

MVC 디자인 패턴으로 변환 된 Google의 공급자 디자인 패턴

웹 사이트 flutterawesome.com 에서 MVC 디자인 패턴을 구현할 샘플 앱을 찾았습니다. e-BazaarBugudi Ramu에서 제공하는 멋진 샘플 앱 으로 Flutter에서 사용할 수있는 다양한 UI 기능을 강조합니다. 그의 허락하에 나는 MVC 패턴을이 앱에 적용하여 그것이 어떻게 될지 확인했습니다. 이 기사에서는 경험에 대해 자세히 설명합니다. 이 과정에서 제가 변환에 사용한 MVC 프레임 워크에서 사용할 수있는 기능을 강조하기 위해 몇 가지 추가 기능이 도입되었습니다. 원래 Flutter의 사용자 인터페이스 기능을 보여주기 위해 설계된 샘플 앱입니다.

e-Bazaar 샘플 앱

단순한 운동

이것은 단지 연습 일뿐입니다. MVC 프레임 워크를 사용하여 앱을 개발하는 동안 타고난 편견을 그릴 수 있다는 것을 알았습니다. 처음부터 앱을 구축하는 동안 프레임 워크와 함께 작동하도록 코드를 '수용'하는 경향이 있습니다. 그런 일이 발생하지 않기를 바랍니다. 그래서 저는 MVC 프레임 워크를 구현할 수있는 방법과 방법을 확인하면서도 '모양과 느낌'과 기능면에서 똑같은 앱을 만들기 위해 기존 샘플 앱을 찾기 시작했습니다. 결국 이것은 프레임 워크였습니다. 모든 앱의 기초가되며 모든 앱에서 작동해야합니다. 이를 위해 샘플 앱인 e-Bazaar를 찾았습니다 .

다시 말하지만,이 연습은 Bugudi Ramu 자신의 프로그래밍 에 대한 반성이 아닙니다 . 그의 아주 좋은 앱입니다. 그는 샘플 앱일뿐이었습니다. 또한 그는 그것에 어떤 종류의 패턴이나 구조도 적용 할 의도가 없었습니다. 흥미로운 사용자 인터페이스 만 반영하는 것이 었습니다. 그게 저를 끌었습니다.

이 기사는 e-Bazaar 샘플 앱에 대한 MVC 구현과는 거의 관련이 없으며 라이브러리 패키지 mvc_application에 의해 구현 된 MVC 패턴 해석 자체에 대해서는 더 자세히 설명합니다 . 실제로이 기사는 소프트웨어 개발에 디자인 패턴을 사용하는 장점을 강조하거나 디자인 패턴을 사용하여 소프트웨어 개발을 가속화하는 속성을 어떻게 강조하는지 보여주기위한 것이 아닙니다. 예를 들어 여러 개발자가 프로젝트에서 개별적으로 동시에 작업 할 수 있도록하는 속성 이를 통해 새로운 개발자는 시간이 지남에 따라 언제든 들어 와서 앱을 개발하거나 나중에 유지 관리 할 수 ​​있습니다. 이 기사는 또한 라이브러리 패키지 mvc_application 의 특정 기능을 강조하기위한 것입니다. 이는 이미 모든 모바일 앱에서 흔히 볼 수있는 기능과 기능을 제공하여 기본 제공 기능으로 전체 개발을 가속화하기 때문입니다.

나는 스크린 샷을 좋아한다. 요점을 클릭하십시오.

항상 그렇듯이, 저는 기사에 코드를 표시하는 것보다 개념을 보여주기 위해 요점보다 스크린 샷을 사용하는 것을 선호합니다. 작업하기가 더 쉽습니다. 그러나 필요한 경우 요점 또는 Github에서 코드를 가져 오기 위해 클릭 / 탭할 수 있습니다. 아이러니하게도 휴대폰보다 컴퓨터에서 모바일 개발에 대한이 기사를 읽는 것이 좋습니다. 게다가 우리는 컴퓨터에서 프로그래밍합니다. 우리 전화가 아닙니다. 지금은.

소셜 미디어에 동영상 없음

또한 이 기사에는 '움직이는 사진'의 기능과 특징을 보여주는 몇 가지 gif 파일이 있습니다. 하지만 인스 타 그램, 페이스 북 등과 같은 플랫폼에서이 기사를 읽을 때는 그러한 파일을 볼 수 없다고 들었습니다. gif 파일이 있어야 하는 곳에 빈 사각형 공간이 보일 것입니다. 이 점에 유의하십시오. medium.com의 브라우저에서 이것을 읽는 것이 좋습니다.

의 시작하자.

Greg Perry의 다른 기사

코드 및 디렉토리의 MVC

이 MVC 프레임 워크와 관련된 작업을 수행 한 모든 프로젝트에서 MVC 디자인 패턴의 세 가지 구성 요소를 반영하도록 디렉토리 구조 자체를 배열했습니다.

모델 -데이터, -인터페이스, 컨트롤러 -로직

이렇게하면 소스 코드가 세 가지 식별 가능한 역할로 구성되어 다른 개발자와 나 자신이 나중에 프로젝트로 돌아와서 특정 코드가있는 위치와 기능을 쉽게 확인할 수 있습니다.

다시 말하지만, 원래 샘플 앱에는 의도 한 디렉터리 구조가 없었습니다. 그러나 오른쪽 아래에 표시된 'MVC'변형에서 디렉토리가 의도 한 구조로 표시되는 것을 볼 수 있습니다. 'MVC'변형은 물론 Github, bazaar 에서 다운로드 할 수 있습니다 .

이 주제에 대한 지난 기사에 익숙하지 않더라도 아래 나열된 각 Dart 파일의 '역할'을 식별 할 수 있습니다. 앱에서 각각 수행하는 작업과 각 파일이 실행될 위치까지도 가능합니다.

bazaar / lib

예를 들어, 위의 디렉토리 목록에 작은 빨간색 화살표가 표시됩니다. view 라는 레이블이 붙은 디렉토리에있는 Dart 파일 목록을 가리키고 있습니다 . 앱의 홈 위젯에있는 서랍 위젯에 나열된 화면이라고 추측했다면 그 위에 엇갈린 상위 디렉토리 이름을 살펴 보겠습니다. 당신이 옳을 것입니다.

디자인 패턴 통합 과정에서 원래 샘플 앱의 Dart 파일 이름과 기존 코드를 최대한 보존하면서 의도 한 구성과 구조를 전달하려고 노력했습니다.

또한이 앱에 대한 로그인 화면이 있다고 추론 할 수 있습니다. 다시 디렉토리를 살펴보면 login 이라는 폴더를 찾을 수 있습니다. 이 폴더에는 MVC 디자인 패턴과 관련된 이름이있는 세 개의 폴더가 있습니다. 따라서 데이터, 화면 및 논리에 대한 코드가 모두있는 위치를 볼 수 있습니다. 이 경우 디렉토리는 알파벳순으로 나열되며 디자인 패턴의 약어 인 MVC 순으로 편리하게 나열되지 않습니다.

bazaar / lib / src / login

그래서 거기 있습니다. 이 앱에 로그인하는 데 관련된 두 개의 화면 (또는보기)이 있음을 알 수 있습니다. 하나는 loginPage.dart 이고 다른 하나는 signupPage.dart 입니다. 각 폴더에는 해당 컨트롤러, 컨트롤러 (파일 이름으로 추측 할 수 있음)가 있으며 '데이터 소스'에는 Google의 Firebase가 포함됩니다. 이 모든 것은 디렉토리 구조를 살펴 보는 것입니다. 따라서 디렉토리 구조 자체를 활용하여 팀이 앱의 '측면'을 분리하도록 위임 할 수 있습니다.

누가 누구에게 말하는가

이러한 디자인 패턴은 MVC와 관련하여 View, Controller 및 Model 사이에서 발생하는 것처럼 특정 통신 라인을 지시하지 않더라도 권장합니다. Life의 모든 것과 마찬가지로 사물을 수정 가능한 부분으로 나누면 개발 및 유지 관리가 훨씬 쉬워집니다. 전체적으로 매우 복잡한 시스템 일 수 있습니다.

Flutter 수용

현재 Flutter 개발자에게 제공되는 모든 인기있는 디자인 패턴은 단순히 Flutter의 '위에'디자인 패턴을 배치한다는 것을 알았습니다. 어떤 경우에는 네이티브 프레임 워크 위에 '그들의 작업 방식'을 부과합니다. 물론 공급자 패턴 (구글이 제안한 패턴)이 가장 방해가되지 않고 Redux 패턴이 가장 많을 수 있습니다. 라이브러리 패키지 mvc_application 에서 제공하는 MVC 디자인 패턴은 싸우지 않고 Flutter 프레임 워크와 함께 작동합니다. 프레임 워크의 특성을 사용하여이를 수용합니다.

우선, State 클래스는 Flutter 용으로 구현 된이 MVC 디자인 패턴에서 중요한 역할을합니다. 그렇기 때문에 State 클래스는 StateMVC 라는 MVC 프레임 워크를위한 새 클래스를 만들기 위해 확장되었습니다 . 일반 State 클래스를 사용하는 대신이 MVC 프레임 워크로 작업 할 때 StateMVC 클래스를 사용하도록 초대됩니다 .

자, 왜 그렇게 하시겠습니까? 몇 가지 이유가 있습니다. 첫째, Flutter에 대한 MVC 디자인 패턴에 대한이 특별한 해석에서 MVC 디자인 패턴에 대해 '보기'로 간주되는 것은 State 개체의 build () 함수 내용이기 때문 입니다. Flutter의 '바닐라 버전'에서 build () 함수 에서 반환 된 위젯 은 앱의 '인터페이스'를 나타냅니다. 음,이 MVC 프레임 워크에서도 마찬가지입니다. 위젯을 반환하는 코드는 MVC의 '보기'에 대한 코드로 표시됩니다. 아래는 StateMVC 클래스 코드의 처음 몇 줄을 보여주는 스크린 샷입니다. 추상 클래스임을 알 수 있습니다. 그 이유는 뷰를 구현하기 때문입니다. 이것이 바로 build () 함수입니다.

StateMVC 클래스

당신의 라이프 사이클은 무엇입니까?

StateMVC 클래스를 사용하는 또 다른 이유 는 모바일 앱의 수명주기와 관련이 있습니다. 내 Android 배경을 사용하여 Flutter를 처음 접하면서 Flutter 프레임 워크에서 모바일 앱의 수명주기가 전달되는 방식을 찾게되었습니다. 모든 앱에는 수명주기가 있으며 개발할 때 고려해야 할 사항입니다. 동료 Android 개발자가 증명했듯이 Android의 유명한 Activity 클래스에는 모바일 앱의 수명주기 동안 발생할 수있는 다양한 '상태'를 쉽게 캡처하는 함수 목록이 있습니다. 글쎄요, Flutter에도 이러한 함수 목록이 있지만 액세스하려면 새 클래스를 만들어야합니다.

Android의 활동 클래스에있는 이벤트 핸들러

함수 didChangeAppLifecycleState () 에서 동일한 정렬을 찾았습니다 . 이 함수는 추상 클래스 WidgetsBindingObserver 에서 찾을 수 있습니다. 이 경우 애플리케이션의 현재 상태를 나타내는 AppLifecycleState 유형의 개체가 전달됩니다. 아래 스크린 샷은 현재 didChangeAppLifecycleState () 함수에 전달 된 가능한 상태를 보여 줍니다 .

믹스 인 StateListener

나는이 클래스가 프레임 워크에 매우 바람직한 특성에 기여한다고 느꼈고, 따라서 클래스 StateMVC 는이 추상 클래스를 확장합니다. 그러면 didChangeAppLifecycleState () 함수 를 통해 애플리케이션의 라이프 사이클에 대한 액세스가 제공 됩니다. 이렇게하면 다른 이벤트 처리기 함수 목록도 제공됩니다. 이러한 모든 기능은 아래의 맨 오른쪽 스크린 샷에 강조 표시되어 있습니다.

이 추상 클래스가 확장되는 동안 StateListener 라는 '빈 클래스' 도 StateMVC 클래스에서 이러한 이벤트 처리기를 구현하는 데 사용됩니다. 그런 다음 앱의 특정 시스템 또는 사용자 이벤트를 처리하기 위해 이러한 함수 중 하나를 선택적으로 재정의 할 수 있다는 아이디어입니다. 매우 유용한 기능입니다.

아래 StateMVC 클래스의 스크린 샷에서 확인할 수 있습니다. 복잡해 보일 수 있지만 걱정하지 마십시오. 결국 프레임 워크이고 복잡해 보인다고 가정합니다. 앱을 빌드하는 데 쉽게 사용할 수 있습니다.

StateMVC 클래스

상태 제어

이제 잠깐, 당신은 말할 수 있습니다! MVC 디자인 패턴에 익숙하다면 특정 시스템 또는 사용자 이벤트를 처리하는 것이 뷰 ( StateMVC )가 아니라 컨트롤러라는 것을 기억할 것 입니다. 당신이 옳을 것입니다! 이것이 StateMVC 클래스를 사용하는 마지막 이유입니다. ControllerMVC 라는 클래스로 작업하는 방법을 알고 있기 때문 입니다. 그러한 사건을 해결하는 데 사용할 클래스입니다. 이 기사에서 곧 그 방법을 볼 수 있습니다. StateMVC 클래스는 발생하는 각 이벤트를 처리하기 위해 컨트롤러 (또는 차례로 컨트롤러)를 호출합니다. 이러한 이벤트를 처리하기 위해 해당 클래스를 구현해야합니다. 그러나 이것이 ControllerMVC 클래스를 사용하는 유일한 이유는 아닙니다.

불변입니다. 그렇게 유지

그렇다면 Flutter에 위젯이라는 불변 객체가있는 이유는 무엇입니까? 예를 들어 StatelessWidget 및 StatefulWidgets 클래스가 변경 불가능한 이유는 무엇입니까? StatefulWidget의 State 객체에는 일반적으로 변경 가능한 콘텐츠가 있습니다.

성능 고려 사항입니다. 컴퓨터 프로그램의 이러한 불변 요소는 정의상 변경되지 않습니다 (한 번 빌드되면 업데이트되지 않음). 결과적으로 CPU 및 GPU 사이클 측면에서 상대적으로 저렴합니다. 잘 됐네요. 그들은 상태를 변경하지 않습니다.

그렇기 때문에 constFlutter 앱의 모든 곳에서 키워드를 볼 수 있습니다. 키워드 const 는 예를 들어 인스턴스화 된 클래스의 값이 컴파일 시간에 알려지고 응용 프로그램의 전체 기간 동안 일정하다는 것을 의미합니다. Flutter와 같은 반응 형 UI에서는 위젯 트리의 많은 부분이 정기적으로 다시 빌드됩니다. 모든 단일 위젯에 사용 된 모든 단일 객체 (및 모든 자체 변수)는으로 표시된 항목을 제외하고 모든 단일 재 빌드에서 반복해서 다시 생성됩니다 const. 이 경우 동일한 인스턴스가 앱 수명 내내 재사용됩니다. 잘 됐네요. 이 샘플 앱에서 많이 사용 된 키워드 const를 볼 수 있습니다.

따라서 Flutter 프레임 워크의 일부는 '상태 비 저장'이므로 변경할 수 없습니다. 이는 의도적으로 설계된 것이며 그대로 유지해야합니다. 그러나 Flutter를 처음 배웠을 때 나와 같으면 의심 할 여지없이 변경 가능한 변수 (예 : StatefulWidget)를 배치하고 다음 경고를 받았습니다.

불변 클래스의 가변 필드

글쎄요, 거기에 있지 않다면, 당신의 앱에 대한 로직을 어디에 배치해야합니까? 본질적으로 이러한 코드는 시스템 및 / 또는 사용자 이벤트에 대한 응답으로 시간이 지남에 따라 변경됩니다! 논리 다! 어디로 갑니까? 글쎄, 나는 그것이 MVC 디자인 패턴에서 어디로 가는지 알고있다. 컨트롤러에 들어갑니다. 그리고이 경우에는 ControllerMVC 클래스로 들어갑니다 . 물론 Flutter의 '바닐라 버전'에서는 이러한 코드가 일반적으로 State 객체로 이동합니다. 모든 코드를 한 곳에서. 그러나이 MVC 라이브러리 패키지를 사용하면 몇 가지 옵션이 있습니다.

이 프레임 워크를 사용하면 원하는 수의 컨트롤러를 특정 뷰 ( StateMVC )에 마음껏 연결할 수 있습니다. 컨트롤러가 두 개 이상 있으면 로직을 더 관리하기 쉬운 부분으로 '분할'할 수 있습니다. 예를 들어 각 컨트롤러는 앱 기능의 다른 측면과 관련 될 수 있습니다. 다른 컨트롤러와 관련 될 필요가 없습니다. 이것은 모듈 코드를 허용합니다. 병렬 개발이 가능합니다. 앱의 개별 부분을 담당하는 별도의 개발자 팀을 가질 수 있습니다. 모두 필요에 따라 가변 변수가 많은 별도의 컨트롤러에 포함됩니다. 모두 하나의보기 ( StateMVC )에 즉시 액세스 할 수 있습니다 .

주와 대화

아래의 첫 번째 스크린 샷은 ControllerMVC 클래스의 시작을 보여줍니다. 두 개의 인접한 스크린 샷에서이 컨트롤러가 실제로 Flutter의 자체 State 개체에서 찾을 수있는 것과 동일한 기능을 공유한다는 것을 확인할 수 있습니다. Flutter를 받아들이십시오. 당신은 이것을 좋아할 것입니다.

ControllerMVC 클래스

이렇게하면 일반적으로 State 객체의 initState () 함수에 배치하는 코드를 수행합니다. 예를 들어 대신 Controller 객체의 자체 initState () 함수에 배치 할 수 있습니다. 물론 Dart 라이브러리 파일이기 때문에이 컨트롤러는 임의의 수의 클래스, 임의의 수의 고급 함수 및 임의의 수의 고급 변수를 포함 할 수 있습니다. 좋은. 그래서 이것은 또 무엇을 의미합니까?

나무를 만드십시오. 트리를 제어하십시오.

아시다시피 Flutter에서 State 객체 의 build () 함수 를 간접적으로 호출하려면 (위젯 트리의 해당 부분을 다시 빌드하기 위해) 해당 클래스의 setState () 함수 를 호출합니다 . 글쎄요. 컨트롤러에도 그 기능이 있습니다. Controller에서 해당 함수를 호출하면 연결된 StateMVC 개체에서 build () 함수 가 호출 됩니다. 이벤트가 발생하고 로직이이를 처리하면 '뷰'에게 해당 이벤트에 대한 응답을 반영하도록 인터페이스를 다시 빌드하도록 지시 할 수 있습니다. 기본적으로 두 사람은 서로 대화 할 수 있습니다.

상태 개체에서 할 수있는 모든 작업은 컨트롤러에서 할 수 있습니다. 모든 컨트롤러에서 할 수 있습니다. 그래서 앱을 구성하는 '논리'를 넣는 곳입니다.

우리는 집이야

샘플 앱으로 돌아가서이 프레임 워크에서 MVC 디자인 패턴을 사용하면 디렉토리 구조에서이 앱의 '홈 페이지'를 쉽게 찾을 수 있습니다. src 디렉토리 아래에 home 이라는 폴더가 있습니다 . 거기에는 view 라는 또 다른 폴더가 있습니다 . 이 폴더가 유일한 폴더이므로 해당 폴더의 코드에는 인터페이스가 포함되어야합니다. 화면입니다. 실제로 이것은 MaterialApp의 명명 된 매개 변수 home에 전달 된 클래스가 해당 폴더에 있음 을 더 많은 경우에 알려줍니다 . 아래를 보면 해당 폴더에 homepage 라는 이름의 단일 Dart 파일이 있습니다.

appbar 디렉토리

위의 후속 스크린 샷을 보면 폴더의 이름 지정 규칙이 Flutter에서 사용 된 키워드를 반영 하고 결과적으로 앱이 무엇을, 어디에 있는지에 대한 아이디어를 제공하는 것을 볼 수 있습니다.

예를 들어 두 번째 스크린 샷에서 '홈'위젯에 앱바, 서랍 및 데이터베이스 ( model )가 포함되어 있는지 쉽게 확인할 수 있습니다 . Home 위젯의 build () 함수 에서 Scaffold 위젯이 반환된다는 것을 올바르게 추측 할 것입니다 . 마지막으로, 마지막 스크린 샷에서 검색 기능과 쇼핑 카트가 앱 바에 표시되는 것을 볼 수 있습니다. 사용자가 검색 아이콘과 장바구니 아이콘을 탭하면 의심 할 여지없이 응답하는 HomeAppBar 라는 컨트롤러가 있습니다 . 모두 한눈에.

당신의 견해는 무엇입니까

아래 스크린 샷은 홈페이지의 '보기'MVC 구성 요소입니다. 다시 말하지만, build () 함수는 Flutter 용 MVC에서보기로 간주되며 아래에 보이는 것은 Home 위젯의 build () 함수 의 내용입니다 . 이제 대부분의 MVC 디자인 패턴과 마찬가지로 View는 일반적으로 연결된 컨트롤러 또는 컨트롤러에 액세스 할 수 있습니다. 아래 스크린 샷의 빨간색 화살표는이 특정 뷰가 HomeAppBar 라는 특정 컨트롤러와 '대화'하는 방식을 강조합니다 .

HomePage 위젯의 build ()

보시 다시피이 View는 Controller에서 두 개의 특정 개체 인 HomeAppBar를 그린 다음 앱의 앱 바에 표시됩니다. 거기에서 분리가 보이십니까? 컨트롤러는 나중에 위의 스크린 샷에서 코드의 한 문자에 영향을주지 않고 '검색 개체'및 '카트 개체'뒤에있는 코드를 자유롭게 변경할 수 있습니다. 모듈 식 프로그래밍. 분리 된 코드.

아래에 해당 컨트롤러의 스크린 샷이 있습니다. 우리는 '검색 객체'와 '카트 객체'가 실제로 두 개의 게터 라는 것을 발견했습니다 . 이들은 선택한 아이콘과 정의 된 이벤트 핸들러가 포함 된 두 개의 IconButton 객체입니다. 또한 디렉터리 구조는 관련된 showSearch 개체가 있고 폴더에는 사용할 '대리자 클래스'가 포함되어 있음을 암시합니다.

HomeAppBar 클래스

두 개의보기 하나의 컨트롤러

이제 홈 위젯의 build () 함수에서도 RecentProducts 클래스 가 인스턴스화됩니다. 음, 이것은 또 다른 StatefulWidget이고 StateMVC 유형의 State 객체도 가지고 있습니다. 따라서 또 다른 View입니다. 그리고 아래에서 볼 수 있듯이 Controller, HomeAppBar를 사용합니다 . 둘 이상의 뷰에서 컨트롤러를 사용할 수없는 법은 없습니다. 실제로 권장됩니다. 이보기는 홈 페이지 하단에 제품의 기본 목록을 표시합니다. 이제이 뷰에 HomeAppBar 컨트롤러도 필요한 이유는 무엇입니까?

RecentProducts 클래스

마지막에 처음으로 새로 고침

설계 상 StatefulWidget, RecentProducts 는 StatefulWidget, HomePage 뒤에 생성 됩니다. 결국 'HomePage'위젯이 생성되고 'HomePage'위젯의 build () 함수에 'RecentProducts'위젯이 생성됩니다 . 그 때문에 설계 상 컨트롤러를 공유하고 해당 컨트롤러가 '새로 고침'명령을 실행하면 ( setState () 함수 호출 ) 마지막 에 추가 된 StateMVC 개체 만 다시 빌드 됩니다. 알 겠어요? 아래의 새로 고침 () 기능이 보이십니까? GIF의 스크린 샷 옆에있는 파일은 아래의 검색 루틴을 보여줍니다. 사용자가, 예를 들어, 단어, 픽업시 청바지 상기 리프레시 () 함수를 호출하여 빌드 화면의 일부에 불과 청바지 표시 'RecentProducts'위젯 () 함수.

HomeAppBar 클래스

따라서 LIFO (Last In, First Out)와 함께 작동합니다. State 개체에 대한 모든 명령은 해당 Controller와 마지막으로 연결된 State 개체에만 영향을줍니다. State 객체 (따라서 View)가 종료되면 이전 State 객체는 이제 '현재'상태 객체로 돌아갑니다. 이해하다? 뷰에 대해 여러 컨트롤러를 가질 수있을뿐만 아니라 해당 컨트롤러의 수명 동안 여러 뷰와 연결할 수 있습니다. 화면에 들어가고 나올 때 하나의 컨트롤러가 화면 뒤에있는 '논리'를 담당 할 수 있습니다. 좋은.

3 개의 컨트롤러와보기

아래는 StatefulWidget, HomePage 의 스크린 샷입니다 . 여기에서 3 개의 컨트롤러가 뷰에 추가되는 방법을 쉽게 볼 수 있습니다. 첫 번째 인 ThemeChanger 가 먼저 추가되므로 StateMVC의 속성 인 controller를 사용하여 쉽게 참조 할 수 있습니다. 나머지 두 개는 생성자 내에서 State 개체에 '추가'되며 다른 방법으로 해당 참조를 가져올 수 있습니다. 예를 들어, 아래 스크린 샷에서 프레임 워크는 Controller, HomeAppBar에 대한 참조를 가져 오는 수단으로 controllerByType () 함수를 제공합니다 .

HomePage 클래스

당신의 선호는 무엇입니까?

시스템 환경 설정을위한 라이브러리 앱이 있습니다. 프레임 워크에서 제공하므로 직접 설치할 필요가 없습니다. 대부분의 앱에 필요한 공통 기능이므로 이미 설정되어 있으며이 MVC 프레임 워크에서 사용할 준비가되었습니다.

Bugudi Ramu 는 샘플 앱을 '다크 모드'로 전환하는 수단을 제공했습니다. 그는이 설정을 저장할 의도가 없었으므로 다음에 샘플 앱을 시작하면 해당 모드가 사라질 것입니다. 괜찮아. 프레임 워크가 도움이 될 수 있습니다.

ThemeChanger 라는 컨트롤러 는 앱의 테마와 그에 따른 모드 설정을 담당합니다. 이 버전의 샘플 앱에서 모드를 변경하면 설정이 시스템의 기본 설정에 쉽게 저장됩니다. 따라서 앱이 다시 시작되면 해당 설정이 다시 사용됩니다. 아래 에서 Controller의 시작 인 ThemeChanger를 살펴 보겠습니다 . 라이브러리를 주목 의 환경 설정은 , 컨트롤러의 호출됩니다 initState () 함수는 함수와 테마를 설정, setDarkMode (). 아래 gif 파일 에서 볼 수 있듯이 setDarkMode () 함수 는 사용자가 스위치를 누를 때마다 호출됩니다.이 함수에는 마지막 '설정'이 시스템의 기본 설정에 저장됩니다.

ThemeChanger 클래스

제품보기

시스템의 기본 설정 기능이 활용되는 또 다른 사례를 살펴 보겠습니다. 아래 스크린 샷은 탭할 때 개별 Bazaar 항목을 표시하는 StatefulWidget의 첫 번째 부분을 보여줍니다. 해당 항목은 별도의 화면에 단독으로 다시 표시됩니다. StateMVC 클래스 가 구현 된 것을 볼 수 있습니다 . 따라서 이것은 물론 이것이 View라는 것을 알려줍니다. 이 화면은 개별 Bazaar 항목을 표시합니다. 아래 의 gif 파일이이를 보여줍니다.

아래의 첫 번째 빨간색 화살표로 강조 표시된 import 문에 의해 해당 컨트롤러가 뷰에 '주입'된 것을 볼 수 있습니다. 아래 두 번째 화살표는 Controller 개체가 인스턴스화되고 StateMVC 개체에 전달되는 위치를 보여줍니다. 그런 다음 ProductDetails 유형 의 변수 con , ControllerMVC 유형 의 속성 controller가 할당 된 StateMVC 생성자에서 개체로 다시 나타납니다 . 이제 해당 State 개체의 build () 함수 에서 사용할 특정 Controller의 인스턴스가 있습니다. 이 모든 것이 지금 어떻게 작동하는지 보십니까?

ProductDetails 클래스

아래의 다음 스크린 샷은 StatefulWidget 클래스 ProductDetails 와 동일한 이름을 가진 해당 Controller 클래스의 스크린 샷 입니다. Dart 프로그래밍 언어가 import 문에서 'as'절을 사용하여 중복 클래스 이름을 수용하는 방법에 유의하십시오. 또한 Prefs 클래스도 가져 와서 컨트롤러의 initState () 및 비활성화 () 함수 에서 호출되는 것을 볼 수 있습니다.

또한 컨트롤러의 View 객체 ( StateMVC )에 대한 참조가 initState () 함수 에서 액세스되는 것을 볼 수 있습니다. 이는 ProductDetailsState 유형 의 인스턴스 변수 state를 StateMVC 유형 의 속성 stateMVC 에 할당하여 수행됩니다 . 그때 뒤로 물러 나면 뷰와 컨트롤러가 어떻게 서로 '대화'할 수 있는지 알 수 있습니다. 컨트롤러에는 '현재'보기에 대한 참조가 있습니다.

이 경우 컨트롤러는 View (State 개체)와 '대화'하여 특정 제품 항목의 이름을 가져 와서 Prefs 정적 함수 인 getBool () 및 setBool ()에 전달합니다. 따라서 사용자가 각 항목을 탭하면 해당 제품 이름이 시스템의 기본 설정에 있는지 여부에 따라 인스턴스 변수 selected 가 true로 설정되고 부울 값 true를 저장합니다. 참이면 오른쪽 상단에 '즐겨 찾기'하트가 표시됩니다. 아래를 참조하십시오.

ProductDetails 클래스

상태 설정; 국가 재건

다시 한 번 새로 고침 () 함수를 눈치 챘을 것 입니다. 사용자가 오른쪽 상단 모서리에있는 작은 하트를 탭한 후에 호출됩니다. 이름에서 알 수 있듯이 앱 화면을 '새로 고침'하는 것입니다. Flutter 프레임 워크 측면에서 위젯 트리의 해당 부분을 다시 빌드하는 것입니다. 일반적으로 setState () 함수 를 사용하여 수행합니다 . 새로 고침 () 함수도이를 호출하지만 빈 함수를 사용합니다.setState((){});

그러나 다른 좋은 프레임 워크와 마찬가지로 옵션이 있습니다. rebuild () 함수 는 똑같은 일을합니다. 이름으로 판단하면 요점에 가깝습니다. 전통적인 방식으로 setState () 함수 를 사용하고 싶다면 그렇게해도됩니다. 실제로 호출 한 함수가 Future 객체를 반환하지 않도록 setState () 함수를 사용하는 것이 좋습니다 . 아래는 동일한 코드 스트레치이지만 대신 rebuild () 및 setState () 두 가지 다른 함수를 사용합니다.

rebuild () 함수를 사용한 다음 setState () 함수를 사용하는 동일한 예제입니다.

보기 제어?

MVC 디자인을 사용하여 수행 한 모든 Flutter 프로젝트에서 앱 UI의 '모양과 느낌'이 뷰 또는 컨트롤러의 책임인지에 대한 결정이 내려지는 것을 발견했습니다. 물론, 문서상 뷰는 앱의 인터페이스에 가장 관심이 많지만 실제로는 컨트롤러가 일부 인스턴스에서 인터페이스를 구성하는 구성 요소를 제공하는 것이 더 타당하다는 것을 알았습니다. 설명하겠습니다.

예를 들어, 오른쪽 상단 모서리에있는 앱의 앱 바에있는 작은 돋보기와 장바구니가 어디에서 왔는지 기억하십니까? 위의 큰 스크린 샷에서 이미 본 적이 있습니다. 그들은 컨트롤러에서오고 있습니다. 이름이 ProductDetails 인 뷰 및 컨트롤러 가 아래에 다시 표시됩니다. 이번에 는 View의 build () 함수 에서 Controller 의 getters , shopping 및 iconButton에 액세스 하는 방법을 볼 수 있습니다 .

컨트롤러는 사용자 이벤트를 처리하는 것입니다. 이 경우, 사용자가 돋보기 나 장바구니를 탭한 경우. 보시다시피 이러한 이벤트에 대한 논리는 컨트롤러에 있습니다. 전체 IconButton 개체를 컨트롤러에 배치하면 개발 및 유지 관리가 훨씬 쉬워집니다. 컨트롤러는 모든 코드를 가져오고 필요한 모든 변수와 로직을 사용하여 이벤트를 처리하고 정보를 시스템 기본 설정에 저장합니다.보기는 더 현명하지 않습니다. 보기 부분은 시스템 기본 설정에 대해 알지 못합니다. 그럴 필요가 없습니다.

보기에서 '하트'아이콘에 좀 더 일반적인 이름 인 iconButton을 어떻게 지정했는지 확인하십시오. 그것은 개발 중이거나 유지 보수 단계에서 '파워'가 어떤 이유로 심장을 스타로 바꾸고 싶다면 게터를 '뷰 사이드'에서 전혀 변경할 필요가 없습니다. 필요한 모든 변경은 컨트롤러에서만 수행됩니다. 모듈 식 프로그래밍. 분리 된 코드.

getter , shopping 을 좀 더 일반적인 용어로 변경해야 할 수도 있습니다 . 아니? 이 구별을 내리는 것은 내 판단의 요구입니다. 자신의 Flutter 프로젝트에서도 만들 수 있습니다.

ProductDetails보기 및 ProductDetails 컨트롤러

들어가서 광고 받기

이 샘플 앱에 명시 적으로 사용되는 두 개의 추가 라이브러리 패키지가 있습니다. 아래 pubspec.yaml 파일의 스크린 샷은 MVC 프레임 워크를 제공하는 데 사용되는 mvc_application 패키지 뿐만 아니라 auth ads 라는 두 개의 추가 패키지도 보여줍니다 . 물론 하나는 앱에 대한 로그인 인증을위한 것이고 다른 하나는 앱에 광고를 게재 할 수 있도록합니다. 이 두 라이브러리 패키지도 작성했습니다.

pubspec.yaml

앱 제어

이제 앱 로그인 및 광고 표시와 관련된 이러한 라이브러리는 어디에서 초기화되고 설정됩니까? 내 말은, 그들은 실제로 앱 의 온라인 쇼핑 측면의 일부가 아닙니다 . 모든 종류의 모바일 앱에 공통적 인 기능입니다. 프레임 워크는 모든 것을 제자리에두고 모든 것을 정리해야합니다. 이제 모든 종류의 앱에서 사용하는 코드를 어디에 넣을까요? 물론 폴더 아래에는 app 이 있습니다. 아래를 참조하십시오.

이 프로젝트의 app 폴더 아래에 컨트롤러 라는 이름을 가진 두 개의 다른 폴더가 있습니다 . 아래 스크린 샷에서 먼저 폴더에있는 항목 인 view . BazaarApp이라는 이름의 '앱보기'클래스입니다. 이 클래스는 '로그인'페이지를 호출 하고 앱 의 온라인 쇼핑 측면으로 이동합니다. 그러나 아래에서 볼 수 있듯이 몇 가지 다른 작업도 수행합니다. 이 시점에서 가장 중요한 것은 'App Controller'를 인스턴스화하고 명명 된 매개 변수 con 을 사용하여 가져옵니다 .

BazaarApp 클래스

BazaarApp 이라는 이름의 '앱 컨트롤러'에 있습니다. 먼저 두 개의 라이브러리 패키지 인 auth ads에 대한 참조를 볼 수 있습니다. Auth 개체는 먼저 앱 컨트롤러의 생성자에서 초기화되는 반면 광고 라이브러리는 인스턴스화되고 앱 컨트롤러의 initState () 함수 에서 설정됩니다 . 모두 독립적입니다. 예를 들어 앱이 종료되면이 두 개체는 앱 컨트롤러의 함수 인 dispose ()에서도 삭제됩니다. 좋은.

BazaarApp 클래스

그들에게 초기화 시간 제공

이제 앱 컨트롤러에서 Future 반환 값이 부울 인 이 init () 함수는 무엇입니까? 위의 스크린 샷에서 볼 수 있으며 사용자가 이미 로그인되어 있는지 확인하고 있다고 추측했다면 맞을 것입니다. 이제이 init () 함수에 익숙하지 않을 수 있지만 MVC 프레임 워크의 중요한 측면이며 아래 스크린 샷을 통해 확인할 수 있습니다. Flutter의 FutureBuilder와 관련이 있습니다.

앱 클래스

로그인 상태 개체에서 사용자가 이미 로그인되어있는 경우 로그인 화면을 표시하는 대신 '홈 페이지'로 바로 이동합니다.

_loginState 클래스

글쎄, 사용자가 이미 로그인했는지 확인하는 데 시간이 걸립니다. 그러나 앱이 진행되기 전에 결정되어야합니다. FutureBuilder를 사용하면 결정될 때까지 화면 중앙에 회전하는 원이 표시됩니다. 실제로 시작시 수행되는 여러 작업 (예 : Prefs 라이브러리 초기화)이 있습니다. init () 함수는 계속하기 전에 앱을 준비하고 설정하기 위해 수행 할 수있는 편리한 장소입니다.

_loginState 클래스

지금 중지

지금은 여기서 멈 춥니 다. 앞으로도 운동의 다른 측면을 계속할 수 있지만 그 과정에 대해 감사하게 생각합니다. 결과 앱은 원래 설계된대로 작동합니다.

간단히 말해, Flutter로 처음 이동하기로 결정했을 때 제공되는 디자인 패턴 라이브러리 패키지가 마음에 들지 않았습니다. 나는 그들이 Flutter 프레임 워크의 '위에 앉았다'는 것을 알았고 그 접근 방식을 모방하지 않고 대신 '작업'했습니다. 예를 들어 Redux는 웹 앱이 가장 인기있는 플랫폼이되었을 때 Facebook에서 설계했습니다. HTML 프로토콜이 앱의 상태를 보존하지 않았기 때문에 상태 관리는 웹 앱에 필수적이었습니다. Flutter를 사용하면 Flutter가 원래 상태를 유지하기 때문에 독립 실행 파일로 돌아갑니다. 독립 실행 형 실행 파일을 실행하는 데스크톱 컴퓨터로 돌아 왔지만 이제 이러한 컴퓨터는 손 안에 들어갈 수 있습니다. 이러한 앱의 경우 MVC로 돌아 왔습니다.

건배.

→ Greg Perry의 다른 이야기

YouTube에서 Flutter 디코딩

Suggested posts

Express.js 시작하기

Express.js 시작하기

Express는 웹 및 모바일 앱을 만드는 경험을 즐겁게 만드는 기능 세트가 포함 된 Node.js 프레임 워크입니다.

Jetpack Compose로 IntelliJ IDEA의 스플래시 화면 모방

Jetpack Compose로 IntelliJ IDEA의 스플래시 화면 모방

IntelliJ IDEA의 최신 버전 (이 출판 당시 2021.1)에는 아래와 같이 다양한 색상의 모양을 포함하는 그리드를 기반으로하는 멋진 스플래시 화면이 있습니다.이 게시물의 목표는이 패턴을 모방 한 Jetpack Compose 컴포저 블을 구현하는 것입니다.