مقدمه
در دنیای نرم افزارهای تجاری باید انتظار حمله بی امان کاربران را برای ارائه خدمت داشت و به همین دلیل باید با نقشه وارد عمل شد. یکی از مهمترین و تکنیکی ترین و نزدیک ترین بخش های طراحی نرم افزارهای تجاری به واژه 'نقشه' همان معماری نرم افزار میباشد. موضوعی که من را برای نوشتن این مطلب آماده کرد این بود که گاها در مقیاس های بزرگتر همه چیز به Clean Architecture ختم نمیشد.
در Clean Architecture هر چیزی جایی دارد ولی در Hexagonal Architecture جاهایی برای چیزها وجود دارد.
معماری Clean Architecture:
در این سبک معماری میتوان گفت که سلسله مراتبی وجود دارد و محدوده ها بخوبی مشخص شده است. و گاهی میتوان این سبک را مثل یک هرم و یا هر شکل دیگری که بیانگر جدا سازی قسمت های مختلف نرم افزار و ایجاد نوعی ارتباط میان آن ها (ترجیحا در لایه های زیرین) باشد, تصور کرد.
حوزه هایی چون Domain و Application و زیرساخت های نرم افزار بخوبی تعریف شده اند و اغلب مجاز به این نیستید که در لایه Domain پکیج هایی چون Entity Framework و یا Hibernate رو نصب کنید. مخصوصا اگر که به Domain Driven Design تمایل دارید. در این سبک شما میبایست ارتباطی معنا دار در عین جداسازی لایه های مختلف نرم افزار و با رعایت اصل Loose Coupling بوجود بیاورید که معنای هر لایه هم نباید زیر سوال برود.
در این سبک از معماری ما در تلاش هستیم تا اصطلاحا نوعی Wire Up را در لایه های زیرین بوجود بیاوریم. و با رعایت این اصول نرم افزار ما به مرحله ای میرسد که همه چیز در سرجای خود قرار دارد و در نگهداری نرم افزار با غافلگیری های کمتری روبرو میشویم!
خوب؟؟!! ما همچین اصولی رو هم لزوما در معماری Hexagonal زیر پا نمیگذاریم!
تفاوت ها از جایی شروع میشه که ما به قدری مقیاس کارمون افزایش پیدا میکنه که این حجم Wire-Up کردن ها افزایش زیادی پیدا میکنه. نرم افزار ما به این نیاز پیدا میکنه که با Rest Api ها کار کنیم. درخواست های Soap رو هم فلان مشتری علاقه منده ارسال کنه. بعضی از کاربران با RabbitMq و بعضی ها اصلا ویندوز اپلیکیشن دارند و یکسری هم تمایل دارند با یک تکنولوژی خیلی خاصی با ما در تعامل باشند. تازه جالب تر هم میشه! ما ده تا data warehouse اس کیو الی داریم. حدودا هفت یا هشت تا Postgresql و چهارتا Oracle و سه چهار تا هم کلاستر RabbitMq و ... پس باید فکر دیگه ای کرد.
این حجم زیاد از تکنولوژی های مختلف و نیازهای متفاوت در اجرای یک usecase ما رو به یک نگرش نه کاملا متفاوت بلکه آینده نگرانه تر سوق میده. معماری که با بقیه معماری ها در مقیاس های کوچکتر در تضاد نباشه و در عین حال بتونه به ما در این سناریوها هم کمک کنه.
معماری Hexagonal:
اغلب این معماری با اصطلاحاتی چون Ports And Adapters شنیده میشود. و در واقع جمیعی از port ها و Adapter ها در کنار هم جمع شده اند و در قلب ماجرا هم فعالیت یا همون UseCase های اپلیکیشن قرار گرفته. Port ها در واقع بیانگر نیاز سرویس گیرنده هستند و Adapter ها هم مسئولیت این رو دارند که نیاز کاربر رو به سرانجام برسونند. مثلا نرم افزار ما کاری چون ثبت نام انجام میدهد. ولی عده ای از طریق یک ui خاص با port مشخص شده و یا عده ای دیگر توسط فرآیند اتوماسیون سازمانی و تکنولوژی های پیچیده تر. همچنین ممکن است که خود عمل ثبت نام در جاهای مختلفی چون دیتابیس های مختلف و یا حتی میکروسرویس های خارجی دیگری انجام شوند و هر کدام میبایست Adapter خاص خود را داشته باشند.
شاید بتوان گفت که Adapter نوعی implementation از Port است.
نتیجه:
معماری شش ضلعی از ارتفاع بیشتری به نرم افزار نگاه میکند و پیاده سازی آن مشخصا نیازمند زمان بیشتر, هزینه بیشتر و البته تخصص بیشتر میباشد و بدیهی است که در هر شرایطی نمیتوان از آن استفاده کرد (درست مثل میکروسرویس ها). در مقابل معماری Clean برای عموم نرم افزارها تجربه ای کاملا موفق بوده و در مقیاس های متوسط یا بزرگ بخوبی ثابت شده است. اما در مقیاس های بسیار بزرگ میتوان از مزایای معماری Hexagonal بهره مند شد و زیرساخت های عظیم میکروسرویسی بوجود آورد و از انطباق پذیری این سبک از معماری آسوده خاطر بود.