معماری شش ضلعی یا بندر و آداپتورها

معماری شش ضلعی ، همچنین به عنوان بنادر و آداپتورها نیز شناخته می شود ، در سال 2005 توسط Alistair Cockburn معرفی شد. Cockburn این مفهوم را برای حل مشکل اتصال تنگ بین منطق کاربرد و وابستگی های خارجی (مانند بانکهای اطلاعاتی ، چارچوب های UI و API) تهیه کرد. هدف اصلی وی این بود که سیستم ها با جدا کردن منطق اصلی تجارت از نگرانی های زیرساختی ، سیستم ها قابل حفظ ، آزمایش و سازگار باشد.
معماری شش ضلعی شباهت هایی با سایر الگوهای معماری دارد که برای ترویج جدایی نگرانی ها و مدولار طراحی شده است.
1⃣ معماری لایه ای (معماری N-stier)
2⃣ معماری تمیز (توسط رابرت سی مارتین – عمو باب)
معماری پیاز 3 (توسط جفری پالرمو)
چرا آن را معماری شش ضلعی خوانده می شود؟
اصطلاح معماری شش ضلعی از شکل شش ضلعی است که برای نمایش بصری سیستم اصلی و تعامل آن با دنیای خارجی استفاده می شود.
🔷 چرا یک شش ضلعی؟
-
شکل شش ضلعی استعاره ای برای نشان دادن بصری هسته سیستم و تعامل آن است.
-
برخلاف یک مستطیل یا دایره ، یک شش ضلعی به معنای ساختار سلسله مراتبی نیست (مانند معماری سنتی N-stier).
-
دارای چندین نقطه اتصال (پورت) است که می توانید به راحتی آداپتورهای مختلف مانند UI ، پایگاه داده یا API های خارجی را وصل کنید.
-
شماره شش مهم نیست ، به سادگی طرف های کافی را برای نمایندگی تمیز و سازمان یافته فراهم می کند.
🔌 پورت ها: ورود به منطق کسب و کار شما
در معماری شش ضلعی ، درگاه ها رابط هایی را نشان می دهند که موارد استفاده یا ویژگی های سیستم را تعریف می کنند. آنها مشخص می کنند که برنامه چه کاری می تواند انجام دهد (به عنوان مثال ، محصولی را به سبد خرید اضافه کنید ، یک محصول را حذف کنید ، کل را محاسبه کنید) ، اما نحوه انجام آن نیست. درگاه ها نقاط ورود به منطق اصلی تجارت شما هستند.
public interface CartService {
void addProduct(Product product);
void removeProduct(String productId);
double calculateTotal();
Cart getCart();
}
در این مثال ، CartService
درگاه اصلی است که موارد استفاده را برای مدیریت سبد خرید تعریف می کند.
🔄 آداپتورها: منطق اصلی خود و دنیای خارج
آداپتورها پیاده سازی هایی هستند که با سیستم های خارجی تعامل دارند و داده ها را بین جهان خارج و منطق اصلی تجارت تبدیل می کنند. در معماری شش ضلعی دو نوع آداپتور وجود دارد:
آداپتورهای اولیه: این ورودی از منابع خارجی ، مانند درخواست کاربر ، UI یا تماس های API. آنها با درگاه های اولیه (موارد استفاده) سیستم تعامل دارند. به عنوان مثال ، یک کنترل کننده استراحت که درخواست HTTP را دریافت می کند و اقدامات را به یک سرویس ارائه می دهد (مانند CartServiceImpl
).
نمونه ای از آداپتور اصلی (کنترل کننده)
@RestController
@RequestMapping("/cart")
public class CartController {
private final CartService cartService;
@Autowired
public CartController(CartService cartService) {
this.cartService = cartService;
}
@PostMapping("/add")
public void addProduct(@RequestBody Product product) {
cartService.addProduct(product);
}
}
CartController
به عنوان یک آداپتور اصلی عمل می کند زیرا درخواست های HTTP (ورودی خارجی) را کنترل می کند و آنها را به CartService (درگاه اولیه) واگذار می کند.
آداپتورهای ثانویه: این سیستم ها را به سیستم های خارجی مانند پایگاه داده ها ، صف پیام یا API می رساند. آنها درگاه های ثانویه را که رابط برای تداوم داده ها یا ادغام های خارجی هستند ، پیاده سازی می کنند.
نمونه ای از آداپتور ثانویه (مخزن)
public class InMemoryCartRepository implements CartRepository {
private Cart cart = new Cart();
@Override
public void save(Cart cart) {
this.cart = cart;
}
@Override
public Cart get() {
return cart;
}
}
آداپتورهای اصلی ➡ به آنها به عنوان دستیار ورودی (کنترل کننده ها ، CLI ، دروازه های API) فکر کنید که درخواست های خارجی را می گیرند و آنها را به سیستم منتقل می کنند.
آداپتورهای ثانویه ➡ آنها را به عنوان گیرنده های خروجی (مخازن ، مشتری های API ، کارگزاران پیام) فکر کنید که از سیستم نتیجه می گیرند و آنها را به دنیای خارج منتقل می کنند.
یک ساختار بسته مثال در جاوا
com.company.cart
│── domain
│ ├── model
│ │ ├── Product.java
│ │ ├── Cart.java
│ ├── repository
│ │ ├── CartRepository.java
│── application
│ ├── service
│ │ ├── CartService.java
│── infrastructure
│ ├── persistence
│ │ ├── InMemoryCartRepository.java
│ ├── controller
│ │ ├── CartController.java
🏗 چگونه این لایه ها در تعامل هستند؟
هنگامی که ما نیاز به تعامل با یک سرویس زیرساختی از یک سرویس برنامه داریم ، ما از اصل وارونگی وابستگی پیروی می کنیم. این اصل نشان می دهد که به جای اینکه مستقیماً به پیاده سازی های مشخص بستگی داشته باشد ، ما وابستگی های لازم را از طریق سازنده کلاس تزریق می کنیم. این رویکرد باعث ایجاد اتصال سست می شود و سیستم را انعطاف پذیر تر و آزمایش آسان تر می کند.
ports در مقابل آداپتورها: درک تفاوت
درگاه ها رابط هایی هستند که سیستم را تعریف می کنند. آنها نمایانگر موارد استفاده از برنامه هستند (به عنوان مثال ، CartService
).
آداپتورها اجرای آن بنادر ، مسئول مدیریت تعامل با جهان خارج هستند (مانند درخواست های HTTP در مورد آداپتورهای اولیه یا تعامل پایگاه داده در مورد آداپتورهای ثانویه).
آیا اجرای پورت اولیه نیاز به آداپتور اصلی دارد؟
شماره. اجرای بندر اولیه (مانند CartServiceImpl
) لازم نیست آداپتور اصلی باشد. در حالی که درگاه های اولیه موارد استفاده را تعریف می کنند ، اجرای آنها صرفاً منطق تجارت است که موارد استفاده را برآورده می کند. آداپتور اصلی (مانند یک کنترلر) یکی از مواردی است که تعامل خارجی را کنترل می کند (به عنوان مثال ، درخواست دریافت ، فراخوانی روش های سرویس).
CartService
یک درگاه اصلی (رابط) است.CartServiceImpl
اجرای پورت اولیه است ، اما آداپتور نیست.CartController
یک آداپتور اصلی است ، زیرا درخواست های HTTP و نمایندگان را به CartService (درگاه اولیه) اداره می کند.
پایان
در معماری شش ضلعی ، پورت ها تعریف می کنند که سیستم چه کاری انجام می دهد (موارد استفاده) ، در حالی که آداپتورها نحوه تعامل سیستم با جهان خارج را تعریف می کنند. اجرای بندر لازم نیست که خود آداپتور باشد. در عوض ، این منطق تجارت است که الزامات تعیین شده توسط بندر را برآورده می کند. از طرف دیگر ، آداپتورها وظیفه اتصال دنیای خارجی را به منطق اصلی از طریق درگاه ها دارند.
این جدایی باعث می شود سیستم برای حفظ ، آزمایش و سازگاری با فن آوری های مختلف خارجی آسانتر شود.
نظر شما در مورد معماری شش ضلعی چیست؟ آیا از آن در پروژه های خود استفاده کرده اید؟ بیایید در نظرات بحث کنیم! 👇💬