Coaspe

Flutter - Architectural overview #Architectural layers #Anatomy of an app #Reactive user interfaces 본문

Flutter/근본

Flutter - Architectural overview #Architectural layers #Anatomy of an app #Reactive user interfaces

Coaspe 2023. 5. 28. 14:35

(Anatomy of an app가 추가되었습니다)

 

flutter 앱은 모든 코드를 재컴파일 필요없이 변화에 대한 stateful 핫리로드를 제공하는 VM에 의해 작동합니다. 릴리즈를 할 때, Flutter 앱은 Intel x64, ARM instructions 명령어 머신코드로 바로 컴파일 되고, 타켓이 웹이라면 Javascript로 컴파일 됩니다. Flutter는 permissive BSD license와 코어 라이브러리의 기능을 보충하는 서드파티 패키지의 번영을 추구하는 생태계를 가지고 있습니다.

 

해당 overview는 여러개의 섹션으로 나뉩니다.

  1. Layer model: Flutter를 구성하는 조각들
  2. Reactive 유저 인터페이스: Flutter 유저 인터페이스 개발의 중심이되는 개념
  3. Widgets 소개: Flutter 유저 인터페이스의 기반이되는 블럭들
  4. 렌더링 과정: 어떻게 Flutter가 UI 코드를 pixels들로 바꾸는지
  5. Platform embedders의 overview: 모바일, 데스크탑 운영체제들이 Flutter 앱들을 실행 할 수 있게 해주는 코드
  6. 다른 코드들을 Flutter와 합치기: Flutter 앱에 사용할 수 있는 다른 테크닉들에 대한 정보
  7. Web 지원: 브라우저 환경에서 Flutter의 특징

Architectural layers

Flutter는 확장가능하고 겹겹이 쌓인 시스템으로 디자인 되었습니다. 이 시스템은 각기근본적인 레이어에 의존하는 일련의 독립된 라이브러리들로 존재합니다. 어떤 레이어도 아래 레이어에 대해 함부로 접근할 수 있는 권한을 가지고 있지 않으며, 프레임워크 수준의 모든 부분은 선택적이고 교체 가능하도록 설계되었습니다.

https://docs.flutter.dev/resources/architectural-overview

Flutter 어플리케이션은 기반이되는 운영 체제에서 다른 네이티브 어플리케이션들과 동일한 방식으로 패키징 됩니다. 플랫폼별 임베더는 진입점을 제공하며 렌더링 surfaces, 접근성, input 같은 서비스에 대한 접근을 위해 기반이되는 운영 체제와 조정하며 메시지 이벤트 루프를 관리합니다. 임베더는 플랫폼에 적절한 언어로 작성되었습니다: 현재 안드로이드는 Java, C++, iOS와 macOS는 Objective-C/Objective-C++, Windoes와 Linux는 C++로 작성되었습니다. 임베더를 사용하여 Flutter 코드는 이미 존재하는 앱에 모듈로 통합 될 수 있고, 코드가 앱의 전체 컨텐츠가 될 수도 있습니다. Flutter는 흔히 사용되는 플랫폼에 대한 임베더를 가지고 있고 다른 임베더 또한 존재합니다

 

Flutter의 코어는 C++로 작성되었고 Flutter 앱을 지원하기 위해 기본적인 필요사항을 제공하는 Flutter engine이 있습니다. 엔진은 새 프레임을 만들 때마다 합성된 장면을 레스터라이징하는 역할을 합니다. Skia를 사용한 그래픽스, 텍스트 레이아웃, 파일 및 네트워크 입출력, 접근성 지원, 플러그인 아키텍처, Dart 런타임과 컴파일 toolchain을 포함함 Flutter의 핵심 API의 낮은 수준의 구현을 제공합니다.

 

이 엔진은 dart:ui를 통해서 Flutter 프레임워크에 노출되며 C++ 코드를 Dart 클래스로 래핑합니다. 이 라이브러리는 입력 가져오기, 그래픽스 그리고 텍스트 렌터링 하위 시스템을 위한 클래스들 같은 낮은 수준의 기본 요소를 제공합니다.

 

보통 개발자들은 Dart 언어로 만들어진 reactive하고 현대적인 프레임워크를 제공하는 Flutter 프레임워크로 Flutter와 상호작용 합니다. 이 프레임워크는 여러 레이어들로 구성된 풍부한 플랫폼, 레이아웃, 기본 라이브러리을 가지고 있습니다. 밑바닥부터  훑어보자면, 우리는

  • 기본 foundational 클래스들 그리고 기반이되는 foundation 위에 일반적으로 사용되는 기능의 추상화를 제공하는 animationpainting, 그리고 gestures 같은 빌딩 블록 서비스를 가지고 있습니다.
  • rendering layer는 레이아웃을 다루기 위한 추상을 제공합니다. 이 레이어를 사용하면 렌더링 할 수 있는 객체의 트리를 빌드 할 수 있습니다.
  • widgets layer는 구성 요소들의 추상입니다. rendering layer에 있는 각 렌더 객체는 widgets layer에 대응되는 클래스가 있습니다. 게다가, widgets layer는 재사용이 가능한 클래스들의 조합을 정의 할 수 있게 해줍니다. 이 레이어가 바로 reactive 프로그래밍 모델이 시작되는 곳 입니다.
  • Material과 Cupertino 라이브러리는 widgets layer의 구성 요소를 사용하여 Material, iOS 디자인 언어를 구현하는 종합적인 컨트롤 셋을 제공합니다.

Flutter 프레임워크는 비교적 작고, 개발자들이 사용할 수 있는 많은 고급 기능들이 패키지로 구현되는데, 여기에는 camera, webview와 같은 플랫폼 플러그인과 핵심 Dart, Flutter 라이브러리를 기반으로하는charactershttp, animations와 같은 플랫폼간 상호 운용이 가능한 기능이 포함됩니다. 이런 패키지 중 일부는 in-app paymentsApple authenticationanimations 같은 covering 서비스를 포함하는 더 넓은 생태계에서 제공됩니다.

 

이 overview의 나머지는 UI 개발의 reactive 패러다임으로 시작하여 계층을 광범위하게 둘러봅니다. 그런 다음 위젯을 함께 구성하고 앱의 일부로 렌더링할 수 있는 객체로 변환하는 방법을 설명합니다. Flutter의 웹 지원이 다른 플랫폼과 어떻게 다른지 간략하게 요약하기 전에 플랫폼 수준에서 Flutter가 다른 코드와 어떻게 상호 운용되는지 설명합니다. 이 모델은 work that came from Facebook for their own React framework에서 영감을 얻었으며, 여기에는 많은 전통적인 디자인 원리에 대한 재고도 포함됩니다.

Anatomy of an app

다음 다이어그램은 flutter create를 사용했을 때 생성되는 Flutter 앱의 구조를 보여줍니다.

https://docs.flutter.dev/resources/architectural-overview

Dart App

  • 위젯들을 만들고자 하는 UI로 구성합니다.
  • 비즈니스 로직을 구현합니다.
  • App 개발자가 관리합니다.

Framework (source code)

  • widgets, hit-testing, gesture detection, accessibility, text input와 같은 높은 수준의 app 제작을 위한 고수준 API를 지원합니다.
  • 앱의 위젯들을 한 장면으로 합성합니다.

Engine (source code)

  • 합성된 장면을 래스터라이징 합니다.
  • graphics, text layout, Dart runtime과 같은 Flutter 코어 API의 저수준 구현을 제공합니다.
  • dart:ui API를 통해 프레임워크에게 엔진의 기능을 제공합니다.
  • 특정 플랫폼과 통합하기 위해 엔진의 임베더 API를 사용합니다.

Embedder (source code)

  • 렌더링 표면, 접근성, 입력과 같은 서비스에 사용을 위해 기반 운영 체제와의 상호작용을 조정합니다.
  • 이벤트 루프를 관리합니다.
  • 플랫폼별 API를 제공하여 임베더를 앱에 통합할 수 있도록 합니다.

Reactive user interfaces

겉으로 보기에 Flutter는 reactive, pseudo-declarative UI framework이며, 개발자는 애플리케이션 상태에서 인터페이스 상태로 매핑을 제공하며, 이 프레임워크는 애플리케이션 상태가 변경될 때 런타임에 인터페이스를 업데이트하는 작업을 담당합니다.

 

대부분의 전통적인 UI 프레임워크에서, 유저 인터페이스의 초기 상태는 이벤트에 대응하여 런타임에 유저 코드에 의해 별도로 업데이트 됩니다. 이 접근 방식의 한 가지 과제는 애플리케이션이 복잡해짐에 따라 개발자가 전체 UI에서 상태 변화가 어떻게 발생하는지 알아야 한다는 것입니다. 예를 들어 다음과 같은 UI를 고려해봅시다.

컬러 박스, 컬러 슬라이더, radio 버튼 등 상태를 변경할 수 있는 곳이 많습니다. 유저가 UI와 상호 작용함에 따라 다른 모든 장소에 변경 사항이 반영되어야 합니다. 더 나쁜 경우에, 주의를 기울이지 않는 다면, 유저 인터페이스의 한 부분에 대한 사소한 변경은 외관상 무관해 보이는 코드 조각에 파급 효과를 일으킬 수 있습니다.

 

이에 대한 한 가지 해결책은 MVC와 같은 접근 방식입니다. 컨트롤러를 통해 데이터 변경 사항을 모델에 적용한 다음, 모델이 컨트롤러를 통해 새로운 상태를 뷰로 푸시하는 방식입니다. 그러니 UI 요소를 만들고 업데이트하는 것은 동기화에서 쉽게 벗어날 수 있는 두 가지 별개의 단계이기 때문에 이 또한 문제가 됩니다.

 

Flutter는 다른 반응형 프레임워크들 처럼 유저 인터페이스를 기본 상태에서 명시적으로 분리함으로써 이 문제에 대한 대안적 접근법을 취합니다. React-style API에서는 UI description만 만들고 프레임워크는 해당 하나의 구성을 사용하여 유저 인터페이스를 생성, 업데이트 합니다.

 

Flutter에서 위젯(React의 구성요소와 유사)은 객체의 트리를 구성하는 데 사용되는 불변 클래스로 표현됩니다. 이러한 위젯은 레이아웃을 위한 별도의 객체 트리를 관리하는 데 사용되며, 이 트리는 합성을 위해 별도의 객체 트리를 관리하는 데 사용됩니다. Flutter는 그 핵심에 트리의 변형된 부분을 효율적으로 다루고, 객체의 트리를 객체의 하위 트리로 변환하고, 이러한 트리에 걸쳐 변화를 전파하기 위한 일련의 메커니즘 입니다.

 

위젯은 상태를 UI로 변환하는 함수인 build() 메소드를 오버라이드하여 유저 인터페이스를 선언합니다.

build() 메소드는 설계상 실행 속도가 빠르며 부작용이 없어야 하고 필요할 때마다 프레임워크에 의해 호출 될 수 있습니다. 

 

이 접근법은 언어 런타임의 특정 특성(특히 빠른 객체 인스턴스화, 삭제)에 의존합니다. 운이 좋게도, Dart는 이런 작업을 잘 수행합니다.

Comments