Use Case Rules و Business Invariants در معماری نرم افزار به چه معناست؟
ناورداهای تجاری (Business Invariants) چیست؟
Business Invariant به قانونی گفته میشود که در تمام طول عمر یک موجودیت یا یک "تجمعی" (Aggregate)، باید همواره صادق (True) باشد. کلمه Invariant به معنای «تغییرناپذیر» یا «ثابت» است.
این قوانین مستقیماً با ماهیت بیزینس در ارتباط هستند و مستقل از هرگونه فناوری یا رابط کاربری عمل میکنند. اگر یک ناوردای تجاری نقض شود، سیستم به یک وضعیت نامعتبر (Invalid State) وارد شده است که از نظر بیزینس فاقد ارزش یا خطرناک است.
ویژگیهای کلیدی Invariants:
-
همیشگی بودن: در هر لحظه از زمان (قبل و بعد از هر عملیات)، این قانون باید برقرار باشد.
-
مکان: جایگاه آنها در قلب مدل دامنه (Domain Model) و درون موجودیتها (Entities) است.
-
استقلال: به این بستگی ندارند که چه کسی یا از چه طریقی (وب، اپلیکیشن، API) درخواست را ارسال کرده است.
مثال:
در یک سیستم بانکی، قانون «موجودی حساب هرگز نباید منفی شود» یک Business Invariant است. مهم نیست کاربر پول برداشت میکند، کارمزد کسر میشود یا انتقال وجه انجام میپذیرد؛ در پایان هر عملیات، این تساوی باید برقرار باشد: $Balance \ge 0$.
قوانین مورد کاربرد (Use Case Rules) چیست؟
Use Case Rules قوانینی هستند که فقط در بستر یک جریان کاری خاص (Workflow) یا یک تعامل مشخص بین کاربر و سیستم معنا پیدا میکنند. این قوانین بیشتر به "نحوه انجام کار" مربوط میشوند تا "ماهیت موجودیتها".
این قوانین اغلب شامل اعتبارسنجیهای ورودی، بررسیهای دسترسی و هماهنگی بین چندین موجودیت مختلف هستند.
ویژگیهای کلیدی Use Case Rules:
-
بسترمند بودن (Contextual): فقط در یک Use Case خاص اعمال میشوند.
-
مکان: در لایه Application یا سرویسهای Use Case قرار میگیرند.
-
تغییرپذیری: ممکن است برای یک موجودیت واحد، در دو Use Case متفاوت، قوانین متفاوتی داشته باشیم.
مثال:
در همان سیستم بانکی، قانون «کاربر برای انتقال وجه بیش از ۱۰ میلیون تومان باید رمز دوم پویا وارد کند» یک Use Case Rule است. این قانون بخشی از ماهیت "حساب بانکی" نیست، بلکه محدودیتی است که فقط در مورد کاربرد "انتقال وجه" اعمال میشود.
تفاوتهای بنیادی: Use Case Rules در مقابل Business Invariants
برای درک بهتر، تفاوت این دو را در چهار جنبه اصلی بررسی میکنیم:
الف) طول عمر و پایداری
Business Invariant محافظت از یکپارچگی دادهها (Data Integrity) را بر عهده دارد. اگر این قانون نقض شود، دادههای دیتابیس "فاسد" تلقی میشوند. اما Use Case Rule محافظت از فرآیند (Process) را بر عهده دارد. اگر نقض شود، صرفاً آن عملیات خاص متوقف میشود، اما به این معنی نیست که موجودیتهای سیستم در وضعیت غیرقانونی قرار دارند.
ب) جایگاه در معماری (Clean Architecture)
در معماری پیازی (Onion Architecture) یا معماری تمیز (Clean Architecture):
-
Invariants در داخلیترین لایه (Entities) قرار دارند.
-
Use Case Rules در لایه اطراف آن (Use Cases / Application Services) قرار میگیرند.
ج) وابستگی به ذینفعان
ناورداها معمولاً توسط متخصصین دامنه (Domain Experts) تعریف میشوند و ریشه در قوانین بنیادی صنف دارند. قوانین مورد کاربرد ممکن است توسط طراحان تجربه کاربری (UX) یا به دلیل ملاحظات امنیتی و فنی وضع شوند.
جدول مقایسهای:
| ویژگی | Business Invariant | Use Case Rule |
| تعریف | قانونی که همیشه باید صادق باشد | قانونی که در یک فرآیند خاص اعمال میشود |
| تمرکز | وضعیت (State) موجودیت | رفتار (Behavior) و جریان کار |
| مکان | Domain Layer (Entities) | Application Layer |
| مثال | موجودی نباید منفی باشد | رمز عبور باید شامل عدد باشد |
| نقض قانون | منجر به وضعیت نامعتبر سیستم میشود | منجر به لغو عملیات فعلی میشود |
چرا به Use Case Rules، اصطلاح Use Case Invariants اطلاق نمیشود؟
این پرسش کلیدی است. چرا ما واژه "Invariant" را برای قوانین سطح Use Case به کار نمیبریم؟ پاسخ در ریشه معنایی کلمه Invariant نهفته است.
۱. فقدان ویژگی "تغییرناپذیری" در طول زمان
اصطلاح Invariant در ریاضیات و منطق به چیزی اطلاق میشود که تحت مجموعهای از عملیاتها، ثابت بماند.
-
Business Invariant ثابت میماند؛ فرقی نمیکند موجودیت را ذخیره کنید، بازیابی کنید یا فیلدی از آن را آپدیت کنید؛ آن قانون باید همیشه برقرار باشد.
-
Use Case Rule ثابت نیست. ممکن است امروز برای "ثبت نام" نیاز به تایید ایمیل باشد (یک Use Case Rule)، اما فردا بیزینس تصمیم بگیرد این مرحله را حذف کند. این تغییر، ماهیت "کاربر" (User) را در سیستم عوض نمیکند، فقط "فرآیند ثبت نام" را تغییر میدهد.
۲. مفهوم "وضعیت" در مقابل "فرآیند"
Invariants نگهبانان State هستند. وقتی میگوییم چیزی Invariant است، یعنی در هر وضعیتی که شیء در آن قرار بگیرد، آن قانون جزئی از هویت آن است.
اما Use Caseها فرآیندهای گذرا هستند. آنها یک شروع، یک میانه و یک پایان دارند. قوانین حاکم بر یک فرآیند، "محدودیتهای اجرایی" (Execution Constraints) هستند، نه ویژگیهای ذاتی وضعیت.
۳. تداخل تعاریف در طراحی شیءگرا
اگر به قوانین Use Case بگوییم Invariant، مفهوم کپسولهسازی (Encapsulation) دچار ابهام میشود. در طراحی دامنه-محور (DDD)، Aggregateها مسئول حفظ ناورداهای خود هستند. اگر ناورداها به سطح Use Case منتقل شوند، عملاً Aggregate دیگر نمیتواند تضمین کند که همیشه در وضعیت معتبری قرار دارد، زیرا بخشی از "صحت" آن به بیرون از خودش (در Use Case) وابسته شده است.
نکته مهم: اصطلاح "Use Case Invariant" یک پارادوکس (تناقضنما) است. چیزی که فقط در یک مورد خاص (Case) صادق است، نمیتواند "ناوردا" (همیشه صادق) باشد.
مثال کاربردی: سیستم رزرو هتل
بیایید این دو مفهوم را در یک سناریوی واقعی مقایسه کنیم:
سناریو: رزرو یک اتاق در هتل.
-
Business Invariant:
-
«تاریخ خروج (Check-out) حتماً باید بعد از تاریخ ورود (Check-in) باشد.»
-
این یک ناورداست. هیچ "رزروی" در هیچ کجای سیستم نباید وجود داشته باشد که تاریخ خروجش قبل از ورودش باشد. این قانون در قلب موجودیت Booking قرار دارد.
-
-
Use Case Rule:
-
«در هنگام رزرو آنلاین، کاربر باید ظرف ۱۵ دقیقه پرداخت را انجام دهد، وگرنه رزرو موقت لغو میشود.»
-
این یک قانون مورد کاربرد است. این قانون بخشی از ماهیت "رزرو" نیست (رزروی که پرداخت نشده باشد، هنوز یک رزرو است که تاریخ ورود و خروج معتبر دارد)، بلکه قانونی برای "فرآیند رزرو آنلاین" است. اگر رزرو توسط اپراتور هتل بصورت تلفنی انجام شود، شاید این قانون ۱۵ دقیقه اصلاً وجود نداشته باشد.
-
پیامدهای اشتباه گرفتن این دو در توسعه نرمافزار
اگر تفاوت این دو را درک نکنیم، سیستم دچار مشکلات زیر میشود:
-
نازک شدن مدل دامنه (Anemic Domain Model): اگر تمام قوانین را در Use Caseها بنویسیم، موجودیتهای ما فقط به کیسههایی برای نگهداری داده (DTO) تبدیل میشوند و منطق بیزینس در لایههای مختلف پخش میشود. این کار باعث میشود تضمین سلامت دادهها غیرممکن شود.
-
پیچیدگی بیش از حد Use Caseها: اگر ناورداهای اصلی بیزینس را در Use Case قرار دهیم، باید در هر Use Case که آن موجودیت را تغییر میدهد، آن قوانین را تکرار کنیم (نقض اصل DRY).
-
تستناپذیری: تست کردن قوانین بیزینسی که در لایه Application گیر کردهاند، دشوارتر از تست کردن موجودیتهای مستقل (Plain Old Java/C# Objects) است.
نتیجهگیری
تفاوت بین Use Case Rules و Business Invariants، تفاوت بین "نحوه انجام یک عملیات" و "ماهیت یک موجودیت" است.
-
Invariants ستونهای اصلی ساختمان بیزینس هستند که هرگز نباید فرو بریزند. آنها در لایه Domain قرار میگیرند تا پایداری و صحت دادهها را تضمین کنند.
-
Use Case Rules راهروها و درهایی هستند که جریان حرکت کاربر را هدایت میکنند. آنها در لایه Application قرار میگیرند تا منطق فرآیندها را مدیریت کنند.
دلیل اینکه به قوانین Use Case، "ناوردا" اطلاق نمیشود این است که این قوانین همیشگی و جزئی از ماهیت وضعیت سیستم نیستند، بلکه محدودیتهایی موقتی و بسترمند برای هدایت رفتار کاربران محسوب میشوند.
0 نظر
هنوز نظری برای این مقاله ثبت نشده است.