UseCase در معماری نرمافزار: پل ارتباطی میان نیاز کاربر و ساختار سیستم
۱. تعریف UseCase (مورد کاربرد) چیست؟
به زبان ساده، یک UseCase توصیفی از مجموعهای از اقدامات است که بین یک بازیگر (Actor) و یک سیستم رخ میدهد تا بازیگر را به یک هدف خاص برساند.
برخلاف ویژگیهای فنی (مثل سرعت دیتابیس یا زبان برنامهنویسی)، Use Case بر روی "چه کاری" (What) تمرکز دارد، نه "چگونه" (How). این ابزار داستان تعامل کاربر با سیستم را روایت میکند.
اجزای اصلی یک UseCase:
-
کنشگر (Actor): کسی یا چیزی که با سیستم تعامل دارد. این میتواند یک انسان (کاربر)، یک سیستم خارجی دیگر (مثلاً درگاه پرداخت)، یا حتی زمان (در فرآیندهای خودکار) باشد.
-
سیستم (System): مرزهایی که نرمافزار ما در آن تعریف میشود.
-
هدف (Goal): نتیجهای که کنشگر میخواهد به آن برسد (مثلاً "خرید بلیط" یا "دریافت گزارش مالی").
-
سناریو (Scenario): توالی گامهایی که برای رسیدن به هدف طی میشود.
۲. جایگاه UseCase در معماری نرمافزار
معماری نرمافزار درباره تصمیمگیریهای کلان و ساختاری است. اما یک معمار چگونه میتواند تصمیم بگیرد که از معماری Microservices استفاده کند یا Monolithic؟ چگونه دیتابیس مناسب را انتخاب میکند؟ پاسخ در نیازهای عملکردی نهفته است که Use Caseها بهترین بیانگر آن هستند.
الف) تعیین مرزهای سیستم (System Boundaries)
اولین وظیفه معمار، مشخص کردن این است که چه چیزی داخل سیستم است و چه چیزی بیرون آن. Use Caseها با تعریف دقیق ورودیها و خروجیها، به معمار کمک میکنند تا مرزهای سیستم را ترسیم کند. هر چیزی که Actor انجام میدهد بیرون از مرز است و پاسخ سیستم، درون مرز.
ب) کشف الزامات معماری (Architectural Drivers)
اگرچه Use Caseها عمدتاً نیازهای عملکردی (Functional Requirements) را بیان میکنند، اما تحلیل دقیق آنها منجر به کشف نیازهای غیرعملکردی (Non-Functional Requirements) میشود که مستقیماً روی معماری تأثیر میگذارند.
-
مثال: در Use Case "خرید بلیط کنسرت در لحظه باز شدن فروش":
-
عملکرد: کاربر بلیط میخرد.
-
تاثیر روی معماری: این سناریو نشان میدهد که سیستم باید توانایی مدیریت هزاران درخواست همزمان را داشته باشد (Scalability & Concurrency). معمار با دیدن این Use Case متوجه میشود که نیاز به مکانیزمهای Caching یا صفبندی (Message Queuing) دارد.
-
ج) سازماندهی ماژولها و سرویسها
- در معماریهای مدرن (مانند Domain-Driven Design)، Use Caseها به شناسایی دامنهها و سرویسها کمک میکنند. معمولاً گروهی از Use Caseهای مرتبط (مانند ثبت سفارش، لغو سفارش، پیگیری سفارش) یک ماژول یا میکروسرویس خاص (مانند Order Service) را شکل میدهند.
۳. ساختار استاندارد یک UseCase معماریمحور
برای اینکه یک Use Case برای معمار سیستم کاربرد داشته باشد، نباید فقط یک متن ساده باشد. ساختار استاندارد شامل موارد زیر است:
۱. نام و شناسه (Name & ID)
باید کوتاه و فعلمحور باشد. مثال: UC-01: انتقال وجه.
۲. بازیگران (Actors)
اولیه (شروعکننده) و ثانویه (سیستمهای پشتیبان).
۳. پیششرطها (Pre-conditions)
وضعیت سیستم قبل از شروع سناریو. (مثال: کاربر باید لاگین کرده باشد و موجودی کافی داشته باشد). این بخش به معمار میگوید که چه وضعیتهایی (State) باید در سیستم مدیریت شوند.
۴. جریان اصلی (Basic Flow / Happy Path)
مسیری که در آن همه چیز درست پیش میرود و کاربر به هدفش میرسد.
-
کاربر گزینه انتقال وجه را انتخاب میکند.
-
سیستم فرم را نمایش میدهد.
-
کاربر مبلغ و مقصد را وارد میکند.
-
سیستم تراکنش را پردازش میکند.
۵. جریانهای جایگزین و استثنا (Alternative & Exception Flows)
این مهمترین بخش برای یک معمار است. معماری خوب معماریای است که شکستها را مدیریت کند.
-
اگر موجودی کافی نبود چه؟
-
اگر ارتباط با بانک قطع شد چه؟
-
اگر کاربر انصراف داد چه؟
طراحیِ مکانیزمهای مدیریت خطا (Error Handling) و تراکنشهای دیتابیس (ACID properties) از این بخش نشأت میگیرد.
۶. پسشرطها (Post-conditions)
وضعیت سیستم پس از پایان سناریو (موفق یا ناموفق).
۴. Use Case در مقابل User Story: تفاوت در چیست؟
در متدولوژیهای چابک (Agile)، اغلب از User Story استفاده میشود. سوال رایج این است: آیا Use Case منسوخ شده است؟
خیر. تفاوت در عمق و ماندگاری است:
| ویژگی | User Story | Use Case |
| هدف | شروع گفتگو و برنامهریزی اسپرینت | مستندسازی دقیق رفتار سیستم |
| جزئیات | کم (روی کارت نوشته میشود) | زیاد (شامل تمام حالات خطا و استثنا) |
| مخاطب | مالک محصول و تیم توسعه | معماران، تحلیلگران و تسترها |
| طول عمر | کوتاه (بعد از پیادهسازی دور ریخته میشود) | بلند (سند زنده سیستم است) |
نکته معماری: معماران برای طراحی سیستمهای پیچیده و Enterprise نمیتوانند تنها به User Storyهای یکخطی اکتفا کنند. آنها نیاز به Use Case دارند تا پیچیدگیهای منطقی و جریانهای داده را درک کنند.
۵. کاربردهای کلیدی UseCase برای تیم فنی
۱. مبنای طراحی API
هر مرحله از یک Use Case معمولاً تبدیل به یک فراخوانی API میشود.
-
سناریو: "کاربر دکمه پرداخت را میزند." $\rightarrow$ معماری: نیاز به طراحی POST /api/payments داریم.
۲. طراحی پایگاه داده (Database Design)
- Use Caseها مشخص میکنند که چه دادههایی باید خوانده (Read) یا نوشته (Write) شوند. با تحلیل سناریوها، معمار میتواند موجودیتها (Entities) و روابط بین آنها را استخراج کند.
۳. پایه و اساس تست (Testing Basis)
- تیم تضمین کیفیت (QA) مستقیماً از روی Use Caseها تستکیسهای خود را مینویسد. اگر Use Case دقیق باشد، تستهای پذیرش (UAT) کاملاً با معماری سیستم همخوانی خواهند داشت.
۴. تخمین هزینه و زمان
- بدون داشتن Use Caseهای مشخص، تخمین زمان پیادهسازی معماری تقریباً غیرممکن است. Use Case واحدی ملموس برای اندازهگیری پیچیدگی سیستم است (روشی به نام Use Case Points).
۶. چالشها و دامهای استفاده از UseCase
با وجود مزایا، استفاده نادرست از Use Case میتواند به معماری آسیب بزند:
-
جزئیات بیش از حد (Analysis Paralysis): اگر Use Case وارد جزئیات رابط کاربری (UI) شود (مثلاً "کاربر روی دکمه آبی کلیک میکند")، معماری را محدود میکند. Use Case باید روی "نیت" تمرکز کند، نه "ظاهر".
-
انفجار سناریوها: تلاش برای پوشش دادن هر حالت نادری میتواند سند را غیرقابل خواندن کند. معمار باید روی سناریوهای تأثیرگذار بر ساختار تمرکز کند.
-
تجزیه تابعی (Functional Decomposition): شکستن Use Caseها به قطعات بسیار ریز که دیگر معنای تجاری ندارند، باعث میشود دیدِ کلی (Big Picture) معماری از دست برود.
۷. تحقق Use Case (Use Case Realization)
در فاز طراحی دقیق، معماران مفهوم انتزاعی Use Case را به عناصر واقعی کد تبدیل میکنند. به این فرآیند Use Case Realization میگویند.
معمولاً برای این کار از نمودار توالی (Sequence Diagram) در UML استفاده میشود. این نمودار نشان میدهد که برای اجرای یک Use Case خاص، کدام کلاسها، کامپوننتها یا سرویسها باید با هم صحبت کنند و چه پیامهایی رد و بدل میشود.
فرآیند ذهنی معمار:
-
Use Case را میخواند.
-
اشیاء (Objects) و سرویسهای درگیر را شناسایی میکند (مثلاً Controller, Service Layer, Repository).
-
تعاملات بین این لایهها را ترسیم میکند تا مطمئن شود معماری لایهبندی شده (Layered Architecture) نقض نمیشود.

UseCase و لایه Application در معماری چون Clean
در Clean Architecture (معماری تمیز)، آن حلقهای که «قوانین کسبوکارِ برنامه» (Application Business Rules) نامیده میشود، همان جایی است که Use Caseها زندگی میکنند. بنابراین، لایه Use Case در معماری تمیز، معادل همان لایه Application در سایر معماریهای لایهای (مانند Onion یا Hexagonal) است.
برای درک دقیقتر این همپوشانی و تفاوتهای ظریف آنها، توضیحات زیر را بخوانید:
۱. تطابق لایهها
در معماری تمیز، رابرت سی. مارتین (Uncle Bob) چهار لایه اصلی را با دایرههای متحدالمرکز نشان میدهد. بیایید ببینیم Use Case کجاست:
-
لایه Entities (مرکز): قوانین تجاری کلان و مستقل (Enterprise Rules).
-
لایه Use Cases (لایه دوم): قوانین تجاری مختص اپلیکیشن (Application Business Rules). $\leftarrow$ این همان لایه Application است.
-
لایه Interface Adapters: کنترلرها، پرزنترها و گیتویها.
-
لایه Frameworks & Drivers: دیتابیس، UI، و ابزارهای خارجی.
بنابراین، وقتی شما در معماریهایی مثل Onion Architecture یا DDD از «لایه Application» یا «Application Services» صحبت میکنید، دقیقاً دارید به همان وظایفی اشاره میکنید که «Use Caseها» در معماری تمیز انجام میدهند.
۲. تفاوت در نامگذاری و نگرش
اگرچه جایگاهشان یکی است، اما زاویه دیدشان کمی متفاوت است:
-
لایه Application (نگرش ساختاری): به این اشاره دارد که "اینجا جایی است که کدهای مربوط به هماهنگیهای نرمافزار قرار میگیرد، نه منطق هستهای (Domain) و نه جزئیات فنی (Infrastructure)."
-
Use Case (نگرش رفتاری): به این اشاره دارد که "این کلاس خاص (مثلاً PlaceOrder) یک سناریوی کاربر را از ابتدا تا انتها اجرا میکند."
در واقع:
لایه Application ظرفی است که Use Caseها (و گاهی اینترفیسها و DTOها) را درون خود نگه میدارد.
۳. وظیفه این لایه چیست؟ (چه Use Case بنامیم، چه Application)
در هر دو تعریف، وظیفه این لایه Orchestration (هماهنگسازی) است. این لایه هیچ "تصمیم تجاری حیاتیای" نمیگیرد (آن کارِ Domain/Entity است)، بلکه فقط کارها را مدیریت میکند:
-
داده را از ورودی (Controller/UI) میگیرد.
-
آن را به فرمت مناسب تبدیل میکند.
-
فراخوانی میکند: "هی Entity! این کار را انجام بده."
-
فراخوانی میکند: "هی Repository! این داده را ذخیره کن."
-
نتیجه را برمیگرداند.
مثال:
تصور کنید یک کلاس دارید به نام TransferMoney.
-
در Clean Architecture به آن میگوییم: TransferMoneyUseCase (یا Interactor).
-
در DDD یا معماریهای لایهای سنتی به آن میگوییم: TransferMoneyApplicationService.
-
کارکرد: هر دو دقیقاً یک کار انجام میدهند.
۴. یک تفاوت ظریف (Entity vs UseCase)
بسیار مهم است که این لایه (Application/Use Case) را با لایه پایینتر (Domain/Entity) اشتباه نگیرید:
| ویژگی | لایه Domain / Entities | لایه Application / Use Cases |
| نوع قوانین | قوانین حیاتی و همیشگی کسبوکار (Enterprise Rules) | قوانین مربوط به گردش کار در این نرمافزار خاص (App Rules) |
| وابستگی | به هیچجا وابسته نیست | فقط به Domain وابسته است |
| مثال | فرمول محاسبه سود بانکی (که همیشه ثابت است) | ترتیب مراحل باز کردن حساب در اپلیکیشن موبایل |
بنابراین...
وقتی در حال پیادهسازی معماری Clean هستید، به جای ساختن پوشهای به نام Application، معمولاً پوشهای به نام UseCases (یا Interactors) میسازید. اما اگر در حال صحبت با معماری هستید که با ادبیات DDD کار میکند، میتوانید با اطمینان بگویید:
"Use Caseهای من همان لایه Application Service شما هستند."
نتیجهگیری
در معماری نرمافزار، Use Caseها نقش نقشهی راه را بازی میکنند. بدون آنها، معماران ممکن است سازهای مستحکم بسازند که نیاز ساکنانش را برطرف نمیکند. Use Caseها تضمین میکنند که معماری سیستم در خدمت اهداف تجاری (Business Goals) است و نه فقط اهداف فنی.
آنها پلی هستند که "دنیای مسئله" (نیاز کاربر) را به "دنیای راهحل" (کد و دیتابیس) متصل میکنند. برای یک معمار موفق، توانایی نوشتن، تحلیل و ترجمه Use Caseها به ساختارهای فنی، یک مهارت حیاتی و غیرقابلانکار است.
0 نظر
هنوز نظری برای این مقاله ثبت نشده است.