آشنایی با عناصری از معماری نرم‌افزار

DDD - Domain Driven Design

خب در ابتدا پیش از DDD، تصمیم دارم برای قسمت اول آن یعنی دامنه یک توضیح کوتاه و خلاصه ای به صورت جداگانه بدهم. دامنه، محیط یا حوزه موضوعی مورد هدف یک برنامه کامپیوتری است. به طور رسمی موضوع مورد نظر یک پروژه برنامه نویسی خاص را نشان می دهد، که یا به صورت محدود یا کلی تعریف شده است. برای مثال یک پروژه برنامه نویسی به طور خاص هدفش ایجاد برنامه ای برای یک مدرسه مشخص باشد. دامنه در اینجا آن مدرسه است. شما یک دامنه را با مشخص کردن مجموعه‌ای از الزامات، اصطلاحات و عملکردهای رایج برای هر برنامه نرم‌افزاری که برای حل آن ساخته شده است، تعریف می‌کنید.

حالا به خود تعریف DDD می‌رسیم. یک نگرش یا رویکرد است، که سعی بر این دارد مدلی را ایجاد و طراحی کند که به دامنه مد نظر پروژه دقیقا نگاشت شود. به عبارتی دیگر، به مقابله مستقیم با پیچیدگی در قلب نرم‌افزار گفته می‌شود. هدف DDD ساده نمودن، ایجاد برنامه های پیچیده با اتصال قطعات نرم افزاری مرتبط به یک مدل همیشه در حال تکامل است. DDD بر 3 اصل زیر بنا می‌شود:

  • تمرکز اصلی پروژه بر روی هسته ی دامنه (دامنه‌ی اصلی) و منطق دامنه
  • آغاز یک همکاری خلاقانه بین 2 گروه یعنی متخصصان فنی و متخصصان دامنه، جهت اصلاح مکرر یک مدل مفهومی که به مشکلات دامنه خاصی می‌پردازد.

طراحی های پیچیده بر اساس مدل یک دامنه.

Hexagonal architecture
معماری شش ضلعی یا معماری پورت‌ها و آداپتورها، یک طرح معماری است که در طراحی نرم‌افزار استفاده می‌شود. هدف، ایجاد مؤلفه‌های برنامه‌ای با اتصال‌هایی سست و ضعیف است یعنی به گونه‌ای که از نظر ساختار نزدیک فشرده نباشد. این مورد کمک می‌کند به راحتی از طریق پورت‌ها و آداپتورها به محیط نرم‌افزار خود متصل شوند. این اتصال های تنک و سست باعث می‌شود اجزا در هر سطحی قابل تغییر و تعویض باشند و مورد دیگر فرایند آزمون خودکار را تسهیل می‌کند. پس می‌توان نتیجه گرفت این معماری برای ساختن سیستم های نرم افزاری است که قابل آزمایش، جدا شده، انعطاف پذیر و قابل نگهداری هستند. تا به اینجا فکر می‌کنم به مزایا این معماری پی برده باشید. این معماری با بیان مختصر منطق در لایه‌های مختلف برنامه، جداسازی نگرانی‌ها و مشکلات را ترویج می‌کند. این امکان سطح بالاتری از انزوا، آزمون پذیری و کنترل روی کد خاص کسب و کار را فراهم می کند، و قاعدتا با این طرح هر لایه از برنامه دارای مجموعه ای دقیق از مسئولیت ها و الزامات است. ویژگی های اساسی (چیزی) را به اختصار بیان می کند. شاید جالب باشد بدانید که کلمه شش ضلعی از قراردادهای گرافیکی می آید که مولفه برنامه را مانند یک سلول شش ضلعی نشان می دهد. هدف پیشنهاد این نبود که شش مرز/پورت وجود داشته باشد، بلکه این بود که فضای کافی برای نمایش رابط‌های مختلف مورد نیاز بین مولفه و دنیای بیرونی باقی بماند.


CQRS - Command Query Responsibility Segregation
در بطن این اصطلاح این ایده وجود دارد که شما می توانید مدلی متفاوت برای به روزرسانی اطلاعات نسبت به مدلی که برای خواندن اطلاعات استفاده می کنید، به کار ببرید. برای برخی موقعیت‌ها، این جداسازی و مرز می‌تواند ارزشمند باشد، اما این مورد را هم باید اضافه کرد و مراقب بود که برای اکثر سیستم‌ها CQRS پیچیدگی خطرناکی را اضافه خواهد کرد. با حرکت به سوی CQRS، به مواردی چون عملکرد، مقیاس‌پذیری و امنیت بالاتری خواهیم رسید. انعطاف پذیری به وجود آمده در طول زمان جهت تکامل سیستم کمک می‌کند. همچنین از ایجاد تداخل ادغام در سطح دامنه توسط دستورات به روزرسانی جلوگیری می‌کند.

حالا وقت آن رسیده به مواردی چون چالش‌های پیاده‌سازی و اینکه به طور خاص در چه مواردی CQRS پیاده‌سازی شود، مناسب‌تر است، بپردازیم. اولین مورد چالشی این است که شاید ایده‌ی روش ساده به نظر بیاید اما در نهایت به طراحی پیچیده در برنامه می‌تواند منجر شود. مورد دیگر این است که اگر چه این روش نیاز به ارسال و دریافت پیام ندارد، اما استفاده از پیام برای پردازش دستورات و انتشار رویدادهای به‌روزرسانی معمول است. پس در این صورت برنامه باید پیام‌های ناموفق و تکراری را نیز مدیریت کند. مورد دیگر پایداری نهایی است به این معنا که توجه داشته باشید که ما دو قسمت به‌روزرسانی و خواندن را از هم جدا کردیم، و ممکن است داده‌هایی که می‌خوانیم قدیمی یا به اصطلاحی کهنه و به‌روز نباشند، پس باید قسمت خوانده شده ما به روز شده و تغییراتی که قسمت update ایجاد می‌کند را انعکاس دهد، جدای از این تشخیص درخواست‌هایی از کاربر که بر اساس داده‌های قدیمی است، هم چالشی جداگانه است.

به طور خلاصه CQRS بهتر است در مواردی چون دامنه‌های اشتراکی که کاربرانی به طور موازی به داده‌هایی مشابه دسترسی دارند مورد استفاده قرار گیرد، که به کمک این روش دستوراتی را با جزئیاتی تعریف کنیم و از تعارض در سطح دامنه جلوگیری صورت گیرد. اما در مواردی چون یک رابط کاربری ساده به سبک CRUD که عملیات دسترسی به داده کافی است، استفاده از این روش پیشنهاد نمی‌شود. به طور کلی استفاده از CQRS را در بخش های محدودی از سیستم خود اعمال کنید، که در آن بیشترین ارزش را دارد.

MVVM (Model - View - ViewModel)
MVVM یک الگوی طراحی ساختاری است که اشیاء را به سه دسته‌ی جداگانه تقسیم می‌کند.
قسمت Model، داده های برنامه را نگه‌داری می‌کنند. مدل‌ها معمولا شامل ساختارها یا کلاس های ساده هستند. مثلا کلاس یک خودرو که متغیرهایی از ویژگی های خودرو دارد در نظر بگیرید، رنگ، سال ساخت و مواردی دیگر. به طور خاص می‌توان گفت این قسمت منطق برنامه را در خود جای داده‌است‌.
View عناصر بصری و کنترل هایی که کاربر روی صفحه نمایش مشاهده می‌کند. پس کاربر مجموعه‌ای از عناصر را مشاهده می‌کند، و ورودی را نیز به View بدهد (مثلا رمز عبور صفحه ورود دیجی‌کالا).
ViewModel لایه‌ای که می‌توان گفت بین دو لایه model و view قرار دارد. داده‌های برنامه که در model جای دارند را به مقادیری تبدیل می‌کنند که می‌توانند در یک View نمایش داده شوند.
احتمال زیادی وجود دارد این الگو برای شما آشنا باشد، کاملا درست است این الگو مشابه الگوی MVC معروف است. ابتدا به طور خلاصه MVC را توضیح می‌دهیم سپس به مقایسه این دو خواهیم پرداخت. در mvc، حرف اول m، model است که شامل داده‌ و منطق مرتبط با آن است. قسمت دوم، view است که می‌توان گفت مدیریت تعامل کاربر را بر عهده دارد و از model درخواست داده می‌کند تا به کاربر نمایش می‌دهد. قسمت سوم، controller رابط بین اجزای model و view می‌باشد.
mvc می‌توان گفت مدل قدیمی‌تری نسبت به mvvm می‌باشد. در mvvm نقطه شروع view است در حالی که در mvc، controller است. در mvvm فرآیند اشکال‌زدایی پیچیده خواهد شد زمانی که پیوندهای پیچیده داده‌ای داشته باشیم. در mvc، خواندن، تغییر، آزمون واحد و استفاده مجدد، مشکل است.

Low code platforms
رویکردهای ماژولار با کد کم و یا بدون کد، به توسعه دهندگان حرفه ای این امکان را می دهد که به سرعت برنامه ها را با بی نیازی از نوشتن کد خط به خط، بسازند. آنها همچنین به تحلیل گران تجاری، مدیران اداری، صاحبان مشاغل کوچک و دیگرانی که توسعه‌دهنده نرم‌افزار نیستند، قادر به ساخت و آزمایش برنامه‌ها می‌شوند. این افراد می‌توانند برنامه‌هایی را با دانش کم یا بدون دانش از زبان‌های برنامه‌نویسی سنتی، کد ماشین یا کارهای توسعه پشت اجزای قابل تنظیم پلت فرم ایجاد کنند. برای مثال در خود جاوا می‌توان پروژه های ساده گرافیکی توسط drag and drop پیاده سازی کرد حال چرا این مثال مطرح شد چون نیازی به تعریف textfeild, label ها با کد نیست صرفا موارد مختلف از پنل سمت چپ کاربر با موس انتخاب می‌شوند و در صفحه‌ی برنامه جای گیری می‌شوند. اجزای برنامه در این مدل ها کشیده و رها کنند، آنها را به یکدیگر متصل کنند و برنامه‌های موبایل یا وب ایجاد کنند.

ESB
یک ESB یا گذرگاه خدمات سازمانی، الگویی است که به موجب آن یک مؤلفه نرم‌افزاری متمرکز، ادغام‌هایی را با سیستم‌های پشتیبان (و ترجمه مدل‌های داده، اتصال عمیق، مسیریابی و درخواست‌ها) انجام می‌دهد و آن ادغام‌ها و ترجمه‌ها را به‌عنوان رابط‌های سرویس برای استفاده مجدد در دسترس قرار می‌دهد جهت برنامه های کاربردی. حالا شاید برای شما سوال باشد که چرا از ESB استفاده می‌شود، چون افزایش چابکی سازمانی با کاهش زمان برای بازاریابی برای ابتکارات جدید یکی از رایج ترین دلایلی است که شرکت ها ESB را به عنوان ستون فقرات زیرساخت فناوری اطلاعات خود پیاده سازی می کنند. یک معماری ESB با ارائه یک سیستم ساده، به خوبی تعریف شده و "قابل اتصال" که به خوبی مقیاس می شود، این امر را تسهیل می کند. مفهوم اصلی معماری ESB این است که شما برنامه های مختلف را با قرار دادن یک گذرگاه ارتباطی بین آنها یکپارچه می کنید و سپس هر برنامه را قادر می سازید تا با BUS صحبت کند. این سیستم‌ها را از یکدیگر جدا می‌کند و به آن‌ها اجازه می‌دهد بدون وابستگی یا آگاهی از سیستم‌های دیگر در BUS ارتباط برقرار کنند.

API gateway
شما به یک دروازه API نیاز دارید زیرا یک نقطه ورودی یکپارچه را در بین APIهای داخلی فراهم می کند. این به شما امکان می دهد دسترسی کاربر را کنترل کنید. و اقدامات امنیتی مانند محدود کردن نرخ را فعال می کند. یک دروازه API همه فراخوان‌های API را از client ها دریافت می‌کند، سپس آنها را با مسیریابی درخواست، ترکیب و ترجمه پروتکل به میکروسرویس مناسب هدایت می‌کند. معمولاً یک درخواست را با فراخوانی چندین میکروسرویس و جمع‌آوری نتایج برای تعیین بهترین مسیر انجام می‌دهد. دروازه API درخواست ها را به یکی از دو روش مدیریت می کند. برخی از درخواست ها به سادگی به سرویس مناسب پروکسی/مسیر می شوند. سایر درخواست‌ها را با ارائه سرویس‌های متعدد انجام می‌دهد. نمونه محبوب دروازه API، Netflix APIاست. خدمات پخش Netflix در صدها نوع مختلف دستگاه مانند تلویزیون، ست تاپ باکس، گوشی های هوشمند، تبلت ها و غیره در دسترس است. این سرویس تلاش می کند یک API یک اندازه برای سرویس پخش خود ارائه دهد.