雖然 Flutter 是以 Dart 寫 UI 與 邏輯
,但我們依然可使用 MVC 架構將 UI 與 邏輯
分離,方便日後維護。
Version
Flutter 3.24
Flutter
- Android 與 iOS 都成功使用 MVC 架構分離 UI 與
邏輯
MVC
controllers
:- 放置所有 controller
- 檔名以
view
結尾,如home_view.dart
,class 為HomeView
views
:- 放置所有 view
- 檔名以
controller
結尾,如home_controller.dart
,class 為HomeController
View
views/home_view.dart
import 'package:flutter/material.dart';
part '../controllers/home_controller.dart';
class HomeView extends StatefulWidget {
const HomeView({super.key});
State<HomeView> createState() => _HomeView();
}
class _HomeView extends HomeController {
Widget build(BuildContext context) {
var appBar = AppBar(
title: const Text('Counter'),
);
var floatingActionButton = FloatingActionButton(
onPressed: _increment,
child: const Icon(Icons.add),
);
var body = Center(
child: Text('$_count'),
);
return Scaffold(
appBar: appBar,
floatingActionButton: floatingActionButton,
body: body,
);
}
}
Line 12
class _HomeView extends HomeController {
Widget build(BuildContext context) {
var appBar = AppBar(
title: const Text('Counter'),
);
var floatingActionButton = FloatingActionButton(
onPressed: _increment,
child: const Icon(Icons.add),
);
var body = Center(
child: Text('$_count'),
);
return Scaffold(
appBar: appBar,
floatingActionButton: floatingActionButton,
body: body,
);
}
}
- View 只剩下 UI,不包含
邏輯
Line 3
part '../controllers/home_controller.dart';
- 使用 part 綁定 Controller
Line 12
class _HomeView extends HomeController {
}
- View
繼承
自 Controller
Line 19
var floatingActionButton = FloatingActionButton(
onPressed: _increment,
child: const Icon(Icons.add),
);
onPress()
:所綁定的increment()
定義於 Controller 而非 View
Controller
controllers/home_controller.dart
part of '../views/home_view.dart';
abstract class HomeController extends State<HomeView> {
var _count = 0;
void _increment() {
setState(() => _count++);
}
}
- Controller 只剩下
邏輯
,不包含 UI
Line 1
part of '../views/home_view.dart';
- 使用 part of 綁定於 View
Line 3
abstract class HomeController extends State<HomeView> {
- Controller 僅為
abstract
class,將在 View 中被繼承
Line 4
var _count = 0;
void _increment() {
setState(() => _count++);
}
- State 與 Method 都定義於 Controller
Conclusion
Flutter 使用 Dart 寫 UI 後,UI 與
邏輯
合而為一,在小專案時尚可,但在中大型專案時會造成單一檔案有太多代碼的隱患,使用 MVC 架構可將 UI 與邏輯
分離,方便日後維護拜 Dart 的
part
與part of
語法,將原本單一檔案的 View 拆成兩個檔案的 View 與 Controller,但對於 Flutter 而言,仍視為同一個檔案,只是邏輯上寫成兩個檔案而已
Reference
Leonidas Kanellopoulos, A Simple way to organize your code in Flutter