معماری برش عمودی آسانتر از آن چیزی است که فکر میکنید 🔪
فرض کنید شما باید یک ویژگی "خروجی گرفتن از دادههای کاربر" 📤 را به اپلیکیشن NET. خود اضافه کنید. کاربران روی یک دکمه کلیک میکنند، سیستم شما خروجی دادههایشان را تولید میکند، آن را در فضای ذخیرهسازی ابری آپلود میکند و یک لینک دانلود امن به آنها ایمیل میکند.
در معماری لایهای فعلی شما با یک ساختار پوشه فنی، احتمالاً شش پوشه مختلف را لمس خواهید کرد: Controllers, Services, Models, DTOs, Repositories, و Validators. شما در solution explorer خود بالا و پایین اسکرول خواهید کرد، رشته افکار خود را از دست خواهید داد، و از خود خواهید پرسید که چرا افزودن یک ویژگی نیازمند ویرایش فایلهایی است که در سراسر پایگاه کد شما پراکنده شدهاند. 🤯
اگر این برایتان آشنا به نظر میرسد، شما تنها نیستید. اکثر توسعهدهندگان NET. با معماری لایهای "استاندارد" شروع میکنند، و کد را بر اساس دغدغههای فنی به جای ویژگیهای بیزینسی سازماندهی میکنند.
اما یک راه بهتر وجود دارد: معماری برش عمودی. ✨
معماری برش عمودی چیست؟🤔
به جای سازماندهی کد خود بر اساس لایههای فنی (Controllers, Services, Repositories)، معماری برش عمودی آن را بر اساس ویژگیهای بیزینسی سازماندهی میکند. هر ویژگی به یک "برش" خودکفا تبدیل میشود که شامل همه چیز مورد نیاز برای آن عملکرد خاص است.
اینطور به آن فکر کنید: معماری لایهای سنتی مانند سازماندهی یک کتابخانه بر اساس اندازه یا رنگ کتاب است 📚، در حالی که برشهای عمودی مانند سازماندهی بر اساس موضوع است. وقتی میخواهید در مورد تاریخ یاد بگیرید، نمیخواهید در کل کتابخانه جستجو کنید، شما تمام کتابهای تاریخ را در یک مکان میخواهید.
رویکرد سنتی در برابر برشهای عمودی
بیایید به مثال خروجی داده ما نگاه کنیم. در اینجا نحوه ساختاردهی این ویژگی در یک پروژه معمولی NET. آمده است:
ساختار لایهای سنتی: 👎
📁 Controllers/
└── UsersController.cs (export endpoint)
📁 Services/
├── IDataExportService.cs
├── DataExportService.cs
├── ICloudStorageService.cs
├── CloudStorageService.cs
├── IEmailService.cs
└── EmailService.cs
📁 Models/
├── ExportDataRequest.cs
└── ExportDataResponse.cs
📁 Repositories/
├── IUserRepository.cs
└── UserRepository.cs
حالا همان عملکرد که به صورت برشهای عمودی سازماندهی شده است:
ساختار برش عمودی: 👍
📁 Features/
└──📁 Users/
└──📁 ExportData/
├── ExportUserData.cs
└── ExportUserDataEndpoint.cs
📁 Create/
└── CreateUser.cs
📁 GetById/
└── GetUserById.cs
پوشه ExportData شامل همه چیز مربوط به خروجی گرفتن از دادههای کاربر است: درخواست، پاسخ، منطق بیزینس و endpoint API.
توجه داشته باشید که من هنوز هم ICloudStorageClient و IEmailSender را تزریق میکنم به جای اینکه آن منطق را مستقیماً در handler قرار دهم. اینها دغدغههای مشترک (cross-cutting concerns) واقعی هستند که چندین ویژگی از آنها استفاده خواهند کرد. نکته کلیدی 🔑، تمایز بین "اشتراکی چون باید باشد" در مقابل "اشتراکی چون این الگو به من گفت" است.