5 دیزاین پترن مهم برای همه مهندسین فلاتر

Singleton Pattern

آیا تا به حال به یک مکان مرکزی برای ذخیره داده‌های سراسری اپلیکیشن مانند تنظیمات کاربر یا مدیریت تم نیاز داشته‌اید؟ الگوی Singleton تضمین می‌کند که تنها یک نمونه از یک کلاس در سراسر برنامه وجود داشته باشد. تصور کنید یک کلاس "SettingsManager" وجود دارد که تم اپلیکیشن را کنترل می‌کند. هر بخشی از رابط کاربری شما می‌تواند به این مدیر دسترسی پیدا کند تا تنظیمات تم فعلی را بازیابی کرده و ویجت‌های خود را به‌طور مناسب استایل دهد. برای اپلیکیشن‌هایی که از GraphQL استفاده می‌کنند، تصور کنید یک کلاینت GraphQL واحد وجود دارد که می‌توانید از آن برای اجرای پرس‌وجوها و تغییرات استفاده کنید. یک مثال حتی رایج‌تر، اتصال websocket است که اپلیکیشن شما تقریباً همیشه تنها به یک مورد از آن نیاز خواهد داشت.

class SettingsManager {
  static final SettingsManager _instance = SettingsManager._internal();

  factory SettingsManager() => _instance;

  SettingsManager._internal();

  ThemeData _themeData = ThemeData.light();

  void switchTheme() {
    _themeData = _themeData.brightness == Brightness.light ? ThemeData.dark() : ThemeData.light();
    // Notify listeners of theme change (implementation omitted for brevity)
  }

  ThemeData getTheme() => _themeData;
}

Factory Method Pattern

وقتی نیاز دارید عناصر رابط کاربری (UI) را به‌صورت پویا بر اساس داده‌ها ایجاد کنید، الگوی Factory Method یک رابط برای ساخت اشیاء ارائه می‌دهد بدون اینکه کلاس دقیق آن‌ها را از قبل مشخص کنید. این روش انعطاف‌پذیری بیشتری را فراهم می‌کند؛ به‌عنوان مثال، یک کلاس کارخانه می‌تواند بر اساس داده‌های دریافتی، انواع مختلفی از دکمه‌ها (مثل دکمه اصلی یا ثانویه) را ایجاد کند.

abstract class ButtonFactory {
  Widget createButton(String text);
}

class PrimaryButtonFactory implements ButtonFactory {
  @override
  Widget createButton(String text) => ElevatedButton(onPressed: null, child: Text(text));
}

class SecondaryButtonFactory implements ButtonFactory {
  @override
  Widget createButton(String text) => TextButton(onPressed: null, child: Text(text));
}

// Usage
ButtonFactory buttonFactory = (isPrimary) => isPrimary ? PrimaryButtonFactory() : SecondaryButtonFactory();
Widget myButton = buttonFactory(true).createButton("Click Me"); // Creates a primary button

Provider Pattern

الگوی Provider یک راهکار سبک برای مدیریت وضعیت است که برای مدیریت کارآمد داده‌ها ایده‌آل است. این الگو از InheritedWidget استفاده می‌کند تا تغییرات داده‌ها را در طول درخت ویجت منتقل کند.

به یک لیست جهانی از هزینه‌های کاربران در یک اپلیکیشن مدیریت هزینه فکر کنید. الگوی Provider به شما امکان می‌دهد یک ExpenseProvider واحد ایجاد کنید که وضعیت شمارنده را نگه دارد و به تغییرات گوش دهد. هر ویجتی در پایین درخت که نیاز به نمایش هزینه‌ها دارد، می‌تواند از طریق این Provider به آن دسترسی پیدا کند.

class MyExpensesProvider with ChangeNotifier {
DateTime startDate = DateTime.now().subtract(const Duration(days: 30));
DateTime endDate = DateTime.now();

bool isLoading = false;
String? error;

List expsenses = [];


MyExpensesProvider() {

getExpenses();
}

getExpenses() async {

}

}

Composition Pattern

قدرت اصلی Flutter در سیستم ویجت‌های ترکیبی آن نهفته است. این سیستم کاملاً با الگوی Composition سازگار است که ایجاد رابط‌های کاربری پیچیده را از طریق ترکیب ویجت‌های کوچک و قابل استفاده مجدد ترویج می‌کند.

این الگو باعث افزایش قابلیت استفاده مجدد، انعطاف‌پذیری و تست‌پذیری می‌شود.

class RoundedButton extends StatelessWidget {
  final String text;
  final VoidCallback onPressed;


  const RoundedButton({required this.text, required this.onPressed});


  @override
  Widget build(BuildContext context) {
    return TextButton(
      onPressed: onPressed,
      child: Container(
        padding: EdgeInsets.all(16.0),
        decoration: BoxDecoration(
          color: Colors.blue,
          borderRadius: BorderRadius.circular(10.0),
        ),
        child: Text(text, style: TextStyle(color: Colors.white)),
      ),
    );
  }
}


// Usage
Widget myScreen = Scaffold(
  body: Center(
    child: RoundedButton(text: 'Click Me', onPressed: () => print('Button Pressed')),
  ),
);

Bloc Pattern

الگوی Bloc یک روش ساخت‌یافته برای مدیریت وضعیت ارائه می‌دهد که لایه رابط کاربری (UI) را از منطق کسب‌وکار (مانند واکشی داده‌ها، محاسبات و غیره) جدا می‌کند. این جداسازی منجر به کدی تمیزتر، قابل نگهداری‌تر و بسیار تست‌پذیرتر می‌شود.

اجزای اصلی Bloc:

  1. Blocs: رویدادها را مدیریت می‌کنند، وضعیت را به‌روزرسانی کرده و تغییرات را منتشر می‌کنند.
  2. Events: نمایانگر اقداماتی هستند که در اپلیکیشن انجام می‌شوند.
  3. State: داده‌هایی هستند که وضعیت اپلیکیشن را در بر می‌گیرند.
  4. BlocProvider: چرخه حیات Bloc را مدیریت کرده و آن را به ویجت‌های فرزند ارائه می‌دهد.

برای کسانی که با TypeScript و React آشنا هستند، این ساختار شباهت زیادی به React Redux دارد.

@immutable
abstract class CounterEvent {}


// Events
class IncrementEvent extends CounterEvent {}


class DecrementEvent extends CounterEvent {}


// State
class CounterState {
  final int counter;


  CounterState(this.counter);
}


// Bloc
class CounterBloc extends Bloc {
  CounterBloc() : super(CounterState(0));


  @override
  Stream mapEventToState(CounterEvent event) async* {
    if (event is IncrementEvent) {
      yield CounterState(state.counter + 1);
    } else if (event is DecrementEvent) {
      yield CounterState(state.counter - 1);
    }
  }
}


// Usage (in UI)
Widget build(BuildContext context) {
  return BlocProvider(
    create: (context) => CounterBloc(),
    child: Scaffold(
      appBar: AppBar(title: Text('Counter')),
      body: Column(
        mainAxisAlignment: MainCenter,
        children: [
          BlocBuilder(
            builder: (context, state) => Text('Count: ${state.counter}'),
          ),
          Row(
            mainAxisAlignment: MainSpaceEvenly,
            children: [
              ElevatedButton(
                onPressed: () => BlocProvider.of(context).add(IncrementEvent()),
                child: Icon(Icons.add),
              ),
              ElevatedButton(
                onPressed: () => BlocProvider.of(context).add(DecrementEvent()),
                child: Icon(Icons.remove),
              ),
            ],
          ),
        ],
      ),
    ),
  );
}

0 🔥
0 🎉
0 😮
0 👍
0 💜
0 👏
میلاد خسروی
نویسنده کد نیوز

برنامه نویس فان | Fun Developer یک آدم ساده که عاشق برنامه نویسی و کد زدنه :) تلاش میکنه تا به بقیه کمک کنه. توسعه دهنده هسته لاراول و فضای اوپن سورس. فاندر پرانتز و کد نیوز.

0+ نظر

برای ثبت نظر ابتدا ورود کنید.

0 نظر

    اولین نفر باش که نظر ثبت میکنی :) یعنی یه کامنت به ما نمیرسه 😁