برنامه نویسی

تبیین مفهوم الگوی حالت در فلاتر

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

باز کردن ذات الگوی دولت

همانطور که در منبع Design Patterns in Dart آمده است، الگوی حالت به عنوان یک الگوی طراحی رفتاری محوری در محصور کردن رفتارهای متنوع برای یک شی بر اساس وضعیت داخلی آن عمل می کند. با این رویکرد، یک شی می تواند رفتار خود را به صورت پویا و بدون نیاز به عبارات شرطی تنظیم کند، در نتیجه پایگاه کد را ساده می کند.

اساساً، هر حالت یک شی با کلاس‌های مجزا نشان داده می‌شود، که به‌عنوان پسوند یا تغییرات یک کلاس حالت اصلی خاص برای آن شی عمل می‌کنند.

غواصی عمیق تر در مفهوم

توضیحات تصویر

داشتن یک شی مانند را در نظر بگیرید Water، جایی که شما a را تعریف می کنید WaterState برای تجسم تغییراتی مانند Solid، Liquid، و Gaseous:

abstract class WaterState {
  //
}

class Solid extends WaterState {
  //
}

class Liquid extends WaterState {
  //
}

class Gaseous extends WaterState {
  //
}
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

علاوه بر این، الگوی حالت به یک جزء حیاتی از الگوی BLoC تبدیل می شود. اگر از الگوی BLoC استفاده می کنید، اساساً از الگوی حالت استفاده می کنید.

سناریوهای ایده آل برای اجرای الگوی دولتی

الگوی State در شرایط زیر مفید است:

  • وقتی یک شی بر اساس حالتش رفتار متفاوتی دارد.
  • اگر تعداد حالت ها قابل توجه باشد و تغییرات حالت مکرر باشد.
  • وقتی یک کلاس دارای چندین شرط است که بر رفتار آن مربوط به مقادیر فیلد تأثیر می گذارد.
  • در مواردی که کد تکراری قابل توجهی برای حالت ها و انتقال های مشابه وجود دارد.

کاربرد الگوی حالت در زندگی واقعی

بیایید اکنون یک مثال عملی را بررسی کنیم که الگوی حالت را در عمل نشان می دهد. کلاس زیر را در نظر بگیرید، جایی که تعاریف حالت شامل متغیرهای و ChangeNotifier:

class CategoryStore extends ChangeNotifier {
  List<String> categories = [];
  bool isLoading = false;
  String error = '';
  IApiDatasource apiDatasource = ApiDatasource();

  void getCategories() async {
    isLoading = true;
    await apiDatasource.getCategories().then((response) {
      response.fold(
        (left) => error = left.message,
        (right) => categories = right,
      );
    });
    isLoading = false;
    notifyListeners();
  }
}
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

را fold() روش مشخص شده در بالا با نوع هر یک مرتبط است، یک عنصر اساسی در برنامه نویسی تابعی که نشان دهنده مقداری است که تحت یکی از دو نوع مشخص شده قرار می گیرد. به طور معمول، یا یک مقدار موفق یا ناموفق را نشان می دهد، دقیقاً مانند مثالی که در آن وجود دارد left نشان دهنده مقدار خطا و right ارزش موفقیت را نشان می دهد.

در کلاس فوق، یک تابع بارگذاری را آغاز می کند isLoading، سپس اقدام به واکشی داده ها از یک API می کند و آن را در آن ذخیره می کند categories متغیر. پس از اتمام بارگذاری، تابع مقدار را به false تنظیم می کند.

برای ساده سازی این کد با استفاده از الگوی حالت، ساختار آن را به صورت زیر انجام می دهیم:

تعریف طبقات دولتی

حالت ها و کلاس های مربوط به آنها در ابتدا اعلام می شوند:

abstract class CategoryState {}

class CategoryInitial extends CategoryState {}

class CategoryLoading extends CategoryState {}

class CategoryLoaded extends CategoryState {
  final List<String> categories;
  CategoryLoaded(this.categories);
}

class CategoryError extends CategoryState {
  final String message;
  CategoryError(this.message);
}
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

پالایش کلاس فروشگاه

در getCategories() تابع، ما حذف isLoading متغیر و معرفی کنید value متغیر، نشان دهنده وضعیت درون است ValueNotifier و پایبندی به CategoryState. در نتیجه، CategoryLoading برای نشان دادن ایالت ما تعیین شده است.

متعاقبا، در fold() روش، اگر درخواست باطل شد، value انتقال به Error وضعیت حامل پیام خطا (left). برعکس، پس از یک نتیجه موفق، آن را اتخاذ می کند Loaded حالت با داده های موجود در right متغیر. این گردش کار، categories و error متغیرها:

class CategoryStore extends ValueNotifier<CategoryState> {
  CategoryStore() : super(CategoryInitial());

  IApiDatasource apiDatasource = ApiDatasource();

  void getCategories() async {
    value = CategoryLoading();
    await apiDatasource.getCategories().then((response) {
      response.fold(
        (left) => value = CategoryError(left.message),
        (right) => value = CategoryLoaded(right),
      );
    });
  }
}
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

را value گیرنده مربوط می شود ValueNotifier، وضعیت فعلی کلاس فروشگاه ما را در خود جای داده است.

نمایش یک نمونه در یک صفحه

class HomePage extends StatefulWidget {
  const HomePage({super.key});

  @override
  State<HomePage> createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  // CategoryStore instance establishment
  CategoryStore store = CategoryStore();

  // Initialization function upon page load
  @override
  void initState() {
    store.getCategories();
    super.initState();
  }

  @override
  void dispose() {
    super.dispose();
    store.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Expanded(
        // Observing the store
        child: ValueListenableBuilder(
          valueListenable: store,
          builder: (context, value, child) {
            // Error handling
            if (value is CategoryError) {
              return Center(
                child: Text(
                  'Error loading categories: ${value.message}',
                ),
              );
            }
            // Presenting loaded data
            if (value is CategoryLoaded) {
              return ListView.builder(
                itemCount: value.categories.length,
                itemBuilder: (context, index) {
                  final category = value.categories[index];
                  return Text(category);
                },
              );
            }
            // Display loading status
            return const Center(child: CircularProgressIndicator());
          },
        ),
      ),
    );
  }
}
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

به این ترتیب، ما الگوی حالت را با موفقیت پیاده سازی کرده ایم! از طریق این رویکرد، ما به مسئولیت واحد و اصول باز/بسته پایبند هستیم و کد را با حذف عبارات شرطی که در غیر این صورت می‌توانند پایگاه کد را پیچیده کنند، ساده‌سازی می‌کنیم.

بسته بندی

سفر شما از طریق این کاوش الگوی ایالت بسیار قدردانی می شود. در حالی که تمرکز روی خود الگوی ایالت بود، من از عمیق‌تر کردن عناصری مانند آن خودداری کردم ValueNotifier و سایر موارد استفاده شده در مثال.

نوشته های مشابه

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *

دکمه بازگشت به بالا