MVC (Model-View-Controller) یک الگوی طراحی است که به شما کمک می کند برنامه Flutter خود را به روشی ساختاریافته سازماندهی کنید. در اینجا خلاصه ای از نحوه عملکرد آن آورده شده است:
مدل
مدل داده ها و منطق تجاری برنامه را نشان می دهد. به طور مستقیم داده ها، منطق و قوانین برنامه را مدیریت می کند.
ویو
View مسئول UI است. داده ها را از مدل به کاربر نمایش می دهد و اقدامات کاربر (مانند فشار دادن دکمه) را به کنترلر ارسال می کند.
کنترلر
کنترلر به عنوان یک واسطه بین Model و View عمل می کند. ورودیهای کاربر را پردازش میکند، مدل را بهروزرسانی میکند، و View را بر این اساس تغییر میدهد.
مثال
در اینجا یک مثال ساده برای نشان دادن الگوی MVC در Flutter آورده شده است:
1. مدل:
class CounterModel {
int _counter = 0;
int get counter => _counter; void increment() {
_counter++;
}
}
2. ویو:
import 'package:flutter/material.dart';
class CounterView extends StatelessWidget {
final int counter;
final VoidCallback onIncrement;
CounterView({required this.counter, required this.onIncrement});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Flutter MVC Example'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'You have pushed the button this many times:',
),
Text(
'$counter',
style: Theme.of(context).textTheme.headline4,
),
SizedBox(height: 20),
ElevatedButton(
onPressed: onIncrement,
child: Text('Increment'),
),
],
),
),
);
}
}
3. کنترلر:
import 'package:flutter/material.dart';
class CounterController {
final CounterModel _model;
CounterController(this._model);
void increment() {
_model.increment();
}
int get counter => _model.counter;
}
void main() {
final model = CounterModel();
final controller = CounterController(model);
runApp(MyApp(controller: controller));
}
class MyApp extends StatelessWidget {
final CounterController controller;
MyApp({required this.controller});
@override
Widget build(BuildContext context) {
return MaterialApp(
home: ValueListenableBuilder(
valueListenable: controller,
builder: (context, CounterModel model, child) {
return CounterView(
counter: model.counter,
onIncrement: controller.increment,
);
},
),
);
}
}
در این مثال:
- مدل (CounterModel) مقدار شمارنده را نگه می دارد و روش هایی را برای دستکاری آن ارائه می دهد.
- View (CounterView) مقدار شمارنده و دکمه ای را برای شروع عمل افزایش نمایش می دهد.
- کنترلر (CounterController) منطق افزایش شمارنده و ارائه مقدار به روز شده به View را مدیریت می کند.
اطلاعات بیشتر در مورد MVC
مزایای استفاده از MVC:
- نگرانی های جداسازی: MVC برنامه را به سه جزء به هم پیوسته جدا می کند، که مدیریت آن را آسان تر می کند، به خصوص که برنامه شما از نظر اندازه و پیچیدگی رشد می کند.
- قابلیت استفاده مجدد: از آنجایی که مولفه های View و Model جدا هستند، می توانید از View های خود با مدل های مختلف یا برعکس استفاده مجدد کنید.
- سهولت تست: تست هر جزء به صورت جداگانه ساده تر می شود. به عنوان مثال، می توانید مدل ها و کنترلرهای خود را بدون نگرانی در مورد رابط کاربری آزمایش کنید.
- قابلیت نگهداری: با سازماندهی کد خود در لایه ها، مکان یابی و رفع اشکالات آسان تر می شود.
معایب استفاده از MVC:
- Boilerplate Code: ممکن است در نهایت کدهای دیگ بخار زیادی بنویسید، به خصوص برای برنامه های ساده.
- پیچیدگی: برای کاربردهای بسیار ساده، MVC میتواند پیچیدگی غیر ضروری ایجاد کند.
یک مثال پیشرفته تر
بیایید مثال قبلی را با افزودن ویژگیهای بیشتر، مانند کاهش شمارنده و نشان دادن تاریخچه تغییرات، گسترش دهیم.
1. مدل: بهروزرسانی برای پشتیبانی از کاهش و حفظ سابقه.
class CounterModel {
int _counter = 0;
List<int> _history = [];
int get counter => _counter;
List<int> get history => _history;
void increment() {
_history.add(_counter);
_counter++;
}
void decrement() {
_history.add(_counter);
_counter--;
}
}
2. ویو: به روز رسانی برای نمایش تاریخچه و یک دکمه کاهش.
import 'package:flutter/material.dart';
class CounterView extends StatelessWidget {
final int counter;
final VoidCallback onIncrement;
final VoidCallback onDecrement;
final List<int> history;
CounterView({
required this.counter,
required this.onIncrement,
required this.onDecrement,
required this.history,
});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Flutter MVC Advanced Example'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'Current counter value:',
),
Text(
'$counter',
style: Theme.of(context).textTheme.headline4,
),
SizedBox(height: 20),
ElevatedButton(
onPressed: onIncrement,
child: Text('Increment'),
),
ElevatedButton(
onPressed: onDecrement,
child: Text('Decrement'),
),
SizedBox(height: 20),
Text(
'History of changes:',
),
Expanded(
child: ListView.builder(
itemCount: history.length,
itemBuilder: (context, index) {
return ListTile(
title: Text('Value: ${history[index]}'),
);
},
),
),
],
),
),
);
}
}
3. کنترلر: به روز رسانی برای رسیدگی به کاهش و تاریخ.
import 'package:flutter/material.dart';
class CounterController {
final CounterModel _model;
CounterController(this._model);
void increment() {
_model.increment();
}
void decrement() {
_model.decrement();
}
int get counter => _model.counter;
List<int> get history => _model.history;
}
void main() {
final model = CounterModel();
final controller = CounterController(model);
runApp(MyApp(controller: controller));
}
class MyApp extends StatelessWidget {
final CounterController controller;
MyApp({required this.controller});
@override
Widget build(BuildContext context) {
return MaterialApp(
home: ValueListenableBuilder(
valueListenable: controller,
builder: (context, CounterModel model, child) {
return CounterView(
counter: model.counter,
onIncrement: controller.increment,
onDecrement: controller.decrement,
history: model.history,
);
},
),
);
}
}
در این مثال پیشرفته، ما عملکردی را برای کاهش شمارنده و نمایش تاریخچه تغییرات اضافه کردیم. این نشان میدهد که چگونه MVC میتواند نیازهای پیچیدهتری را در حالی که کد را منظم و قابل نگهداری نگه میدارد، برطرف کند.
نکته کلیدی در اینجا این است که MVC می تواند به شما در ساخت برنامه های مقیاس پذیر و قابل نگهداری با جداسازی واضح نگرانی ها کمک کند.
این معماری به شما کمک می کند تا کد خود را تمیز و قابل مدیریت نگه دارید، به خصوص که برنامه شما در پیچیدگی بیشتر می شود.