آیا این منطق میتواند روی یک Domain Entity قرار بگیرد؟
بیشتر "shared business logic"ها در واقع:
• ءdata access هستند
• ءdomain logicی هستند که باید روی Entity قرار بگیرند
• ءabstractionهای زودهنگاماند
اگر نیاز دارید یک side effect در Feature دیگری ایجاد کنید، پیشنهاد میشود:
از Messaging و Event استفاده کنید
یا Feature مقصد یک Facade (یک API عمومی) برای این عملیات ارائه کند
زمانی که Duplication انتخاب درست است 🔁
گاهی چیزی Shared به نظر میرسد، اما واقعاً Shared نیست.
// Features/Orders/GetOrder
public record GetOrderResponse(Guid Id, decimal Total, string Status);
// Features/Orders/CreateOrder
public record CreateOrderResponse(Guid Id, decimal Total, string Status);
هر دو یکساناند.
وسوسهٔ ساخت یک SharedOrderDto شدید است.
مقاومت کنید.
هفتهٔ بعد، GetOrder نیاز به tracking URL پیدا میکند.
اما CreateOrder وقتی اجرا میشود هنوز Shipping انجام نشده؛ پس URL وجود ندارد.
اگر DTO مشترک ساخته بودید:
یک property nullable اضافه میشد
نیمی از مواقع خالی بود
و باعث ابهام و Coupling میشد.Duplication ارزانتر از Abstraction اشتباه است.
ساختار عملی 🏗
این ساختاری است که یک پروژهٔ بالغ Vertical Slice Architecture معمولاً دارد:
📂 src
└──📂 Features
│ ├──📂 Orders
│ │ ├──📂 CreateOrder
│ │ ├──📂 UpdateOrder
│ │ └──📂 Shared # اشتراکگذاری مخصوص Orders
│ ├──📂 Customers
│ │ ├──📂 GetCustomer
│ │ └──📂 Shared # اشتراکگذاری مخصوص Customers
│ └──📂 Invoices
│ └──📂 GenerateInvoice
└──📂 Domain
│ ├──📂 Entities
│ ├──📂 ValueObjects
│ └──📂 Services # منطق domain مشترک
└──📂 Infrastructure
│ ├──📂 Persistence
│ └──📂 Services
└──📂 Shared
└──📂 Behaviors
توضیح بخشها:
🔸️ءFeatures → Sliceهای مستقل. هرکدام صاحب Request/Response خودشاناند.
🔸️ءFeatures/[Name]/Shared → اشتراکگذاری محلی بین Sliceهای مرتبط یک Feature.
🔸️ءDomain → Entities، Value Objects، Domain Services.
🔸️ءInfrastructure → کل نگرش فنی سیستم.
🔸️ءShared → فقط Cross-Cutting Behaviors.
قوانین 🧠
بعد از ساخت چند سیستم با این معماری، به این اصول رسیدهام:
1️⃣ ءFeatures صاحب Request/Response خودشان هستند. بدون استثنا.
2️⃣ منطق تجاری را تا حد ممکن وارد Domain کنید.
ءEntities و ValueObjectها بهترین مکان برای اشتراکگذاری واقعی Business Rules هستند.
3️⃣ اشتراکگذاری در سطح Feature-Family را محلی نگه دارید.
فقط اگر کد فقط در Orderها استفاده میشود → همانجا نگه دارید.
4️⃣ ءInfrastructure بهصورت پیشفرض Shared است.
Persistence، Logging، HTTP Clients
5️⃣ ءRule of Three را رعایت کنید.
تا وقتی سه استفادهٔ واقعی و مشابه ندارید → abstraction نکنید.
نتیجهگیری 📌
ءVertical Slice Architecture از شما میپرسد:
«این کد متعلق به کدام Feature است؟»
سؤال اشتراکگذاری در واقع میپرسد:
«اگر جوابش چند Feature است چه کنم؟»
پاسخ:
پذیرفتن اینکه برخی مفاهیم واقعاً cross-feature هستند،
و دادن یک محل مشخص به آنها بر اساس ماهیتشان: Domain، Infrastructure یا Behavior.
هدف، حذف کامل Duplication نیست.
هدف این است که وقتی نیازها تغییر میکند، تغییر کد ارزان و ساده باشد.
و نیازها همیشه تغییر میکنند.
Thanks for reading.
And stay awesome! ✨
🔖هشتگها:
#VerticalSliceArchitecture #SoftwareArchitecture #DotNet #CSharp #ArchitecturePatterns