وضعیت mahdi.sg مرداد ۲۸, ۱۴۰۳

وضعیت (State)


هـــدف

حالت یک الگوی طراحی رفتاری است که به یک شیء اجازه می‌دهد رفتار خود را هنگام تغییر حالت داخلی خود تغییر دهد. به نظر می‌رسد که شیء کلاس خود را تغییر داده است.

State Design Pattern

مـسئـــلـه

الگوی وضعیت، ارتباط نزدیکی با مفهوم ماشین حالت محدود دارد.

Finite-State Machine

ماشین حالت محدود

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

همچنین می‌توانید این رویکرد را به اشیاء اعمال کنید. تصور کنید که ما یک کلاس سند داریم. یک سند می‌تواند در یکی از سه حالت پیش‌نویس، تعدیل و منتشر شده باشد. متد انتشار سند کمی متفاوت در هر حالت عمل می‌کند:

در پیش‌نویس، سند را به تعدیل منتقل می‌کند.

در تعدیل، سند را عمومی می‌کند، اما فقط اگر کاربر فعلی یک مدیر باشد.

در منتشر شده، هیچ کاری انجام نمی‌دهد.

Possible states of a document object

حالت‌های ممکن و انتقال‌های یک شیء سند

ماشین‌های حالت معمولاً با تعداد زیادی عبارت شرطی (if یا switch) پیاده‌سازی می‌شوند که رفتار مناسب را بسته به حالت فعلی شیء انتخاب می‌کنند. معمولاً، این “حالت” فقط مجموعه‌ای از مقادیر فیلدهای شیء است. حتی اگر قبلاً در مورد ماشین‌های حالت محدود چیزی نشنیده باشید، احتمالاً حداقل یک بار یک حالت را پیاده‌سازی کرده‌اید. آیا ساختار کد زیر زنگ را به صدا در می‌آورد؟

class Document is
    field state: string
    // ...
    method publish() is
        switch (state)
            "draft":
                state = "moderation"
                break
            "moderation":
                if (currentUser.role == "admin")
                    state = "published"
                break
            "published":
                // Do nothing.
                break
    // ...

بزرگترین ضعف یک ماشین حالت مبتنی بر شرط‌ها زمانی آشکار می‌شود که شروع به افزودن حالت‌ها و رفتارهای وابسته به حالت بیشتر و بیشتر به کلاس سند کنیم. اکثر متدها شامل شرط‌های عظیمی خواهند بود که رفتار مناسب یک متد را بر اساس حالت فعلی انتخاب می‌کنند. چنین کدی بسیار دشوار برای نگهداری است زیرا هر تغییری در منطق انتقال ممکن است نیاز به تغییر شرایط حالت در هر متد داشته باشد.

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

الگوی حالت پیشنهاد می‌کند که برای همه حالت‌های ممکن یک شیء کلاس‌های جدید ایجاد کنید و تمام رفتارهای وابسته به حالت را به این کلاس‌ها استخراج کنید.

به جای پیاده‌سازی تمام رفتارها به تنهایی، شیء اصلی، که زمینه نامیده می‌شود، مرجعی به یکی از اشیاء حالت ذخیره می‌کند که حالت فعلی آن را نشان می‌دهد و تمام کارهای مرتبط با حالت را به آن شیء واگذار می‌کند.

Document delegates the work to a state object

سند کار را به یک شیء حالت تفویض می‌کند.

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

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

دکمه‌ها و سوئیچ‌ها در گوشی هوشمند شما بسته به حالت فعلی دستگاه رفتار متفاوتی دارند:

هنگامی که گوشی قفل نشده است، فشار دادن دکمه‌ها منجر به اجرای عملکردهای مختلف می‌شود.

هنگامی که گوشی قفل است، فشار دادن هر دکمه‌ای منجر به صفحه قفل می‌شود.

هنگامی که شارژ گوشی کم است، فشار دادن هر دکمه‌ای صفحه شارژ را نشان می‌دهد.

ســاخــتـــار

Structure of the State design pattern

 

 

برای مطـالعـه متن کامل مقالــه، مجموعه کــــدها، نحوه پیاده سازی، مزایا و معایب و روابط با الگوهای دیگر، ایــنــجـــا کلیک کنید.