بررسی چند مفهوم در معماری نرم افزار

در این مقاله به صورت خیلی خلاصه و سطحی به سراغ ۲۰ مفهوم در معماری می رویم و هدف مان این است که اگر جایی درباره اینها صحبت شد، حداقل درکی سطحی از موضوع بحث داشته باشیم. سعی می شود در پایان منابعی نیز برای هر کدام معرفی شود تا اگر نیاز و علاقه به مطالعه بیشتر داشتید،‌ به سراغ آنها بروید.۱ ) رویکرد طراحی دامنه محور (Domain-Driven Design): با خواندن نام این رویکرد طبیعتا اطلاعات خاصی به ما داده نمی شود و حتی ممکن است گیج شویم. اصلا منظور از دامنه چیست؟ طراحی براساس دامنه دقیقا به چه صورت است؟ خب برای فهم این معماری باید اول به سراغ یک مفهوم برویم و آن هم دامنه است. دامنه به نوعی دلیل وجود نرم افزار است. کاربر برای چه دلیلی با آن نرم افزار کار می کند؟ آن دلیل می شود دامنه. به تعریف تخصصی میتوان گفت دامنه بیانگر حوزه کلی یک نرم افزار است. مثلا دیجی کالا یک دامنه فروش است. حالا تکلیف طراحی دامنه محور چیست؟ به طور کلی این طراحی می گوید که زبان و کد یک نرم افزار که به نوعی زیربنا و اجزای اصلی تشکیل دهنده آن هستند باید با دامنه آن مطابقت داشته باشد. به زبان دیگر، تعامل پیوسته و عمیق بیزینس و کسب و کار با توسعه نرم افزار است. در ادامه جمله ای از اریک اوانز، خالق این معماری بخوانیم : برای ایجاد نرم افزار خوب، باید بدانید که آن نرم افزار چیست. شما نمی توانید یک سیستم نرم افزاری بانکی ایجاد کنید مگر اینکه درک خوبی از چیستی بانکداری داشته باشید، باید حوزه بانکداری را درک کنید.برای مطالعه بیشتر :‌ مطلبی نسبتا مفصل با توضیحاتی در مورد مفاهیم خاص این معماری :‌ لینک برای بررسی تخصصی تر و نگاهی عمیق به این معماری :‌ لینک ۲ )‌ معماری شش ضلعی (Hexagonal Architecture) : معماری هگزاگونال یا معماری پورت و آداپتور، نوعی از معماری نرم افزار است که در آن ورودی کاربر و یا سرویس های خارجی در تعاملی دو طرفه با نرم افزار از طریق پورت و آداپتور هستند. این مسئله باعث ایجاد یک لایه ایزوله شده و جدا برای بدنه اصلی نرم افزار می شود که در تعاملات از تغییر مصون می ماند. حتی میتوان گفت که این لایه ایجاد شده برای بدنه نرم افزار باعث می شود که منطق نرم افزار پیاده شده ما از تغییر تکنولوژی ها نیز در امان باشد و تغییری نکند. چرا که ما یک سری پورت و اداپتور داریم که به عنوان درگاه ورودی و خروجی نرم افزار عمل کرده و نوعی کنترل را اعمال می کنند. اما سوالی که پیش مي آید این است که اصلا این پورت و آداپتور به چه معناست و کار آنها چیست؟ به طور خلاصه میتوان پورت را یک درگاه ورودی و خروجی دانست که امکان تعامل با نرم افزار را از طریق آداپتورها فراهم می کند. مانند تعامل با دیتابیس، سرویس اعتبارسنجی کاربران و غیره. اداپتور اما به نوعی تعامل با نرم افزار از طریق پورت را از طریق یک تکنولوژی خاص ارتباطی فراهم می کند. به عنوان مثال REST Controller نشان دهنده یک آداپتور است که بر پایه تعاملات REST ارتباط با نرم افزار را ممکن می کند. نکته مهم این است که یک پورت میتواند چندین آداپتور داشته باشد که به نسبت نیاز ورودی و یا خروجی آن پورت تعیین می شوند. برای درک بهتر به شکل زیر نگاه کنید.برای مطالعه بیشتر به این لینک مراجعه کنید. ۳) معماری CQRSبیاید دستورها را از کوئری ها جدا کنیم. این شعار اصلی این روش است. حتی اگر بخواهیم دقیق تر بگوییم شهود اصلی این معماری این است که محل ذخیره داده از محل برگرداندن داده جدا باشد. البته به این معنا نیست که باید و حتما دو دیتابیس داشته باشیم بلکه بیشتر تلاش برای جداسازی این دو سرویس است. در بیشتر سامانه های نرم افزاری خواندن اطلاعات از وارد کردن آن و یا به روزرسانی اطلاعات بیشتر اتفاق میفتد، پس با این روش به خوبی میتوان به روی هر سرویس تمرکز جداگانه ای گذاشت و یا حتی در صورت نیاز منابع هر کدام را متفاوت تعیین کرد. حتی در بعضی نرم افزارها، خواندن داده ها از یک دیتابیس no sql انجام می شود و یا نوشتن اطلاعات بر روی یک دیتابیس relational صورت می گیرد و یا برعکس. در کل این معماری یک نوع تفکیک میان مسئولیت بر روی دیتابیس انجام می دهد که شاید به تنهایی یک معماری مستقل نباشد اما میتواند تاثیر بزرگی بر روی معماری کلی سیستم بگذارد. به عنوان مثال شما در می يابید که خواندن اطلاعات شما بسیار بیشتر از نوشتن اطلاعات صورت می گیرد. خب این مسئله باعث می شود که شما دید بهتری نسبت به سامانه خود داشته باشید و با کمک آن بقیه مسائل را هم تغییر دهید.اما در این معماری با تمام مزایایی که ایجاد می کند مشکلات پیچیدگی زیاد و در صورت استفاده از دو دیتابیس مشکلات sync بودن آنها با هم ایجاد می شود. بعضا دیده می شود که یک دیتابیس برای سرچ ایجاد می کنند مانند elasticsearch که سرعت خوبی دارد در این زمینه و دیتابیس اصلی را به عنوان مثال Mongo می گذارند. این کار سرعت خوبی در عملکرد سیستم ایجاد می کند اما هماهنگی داده ها و به روزرسانی آنها مسئله مهمی ست که باید در نظر گرفت.برای اطلاعات بیشتر و صرفا داشتن یک دید کلی :‌ لینکاطلاعات تکمیلی تر و روش های مختلف پیاده سازی هم این لینک مناسب است.۴) مفهوم MVVMاین معماری نرم افزار را به ۳ بخش کلی Model,View,View Model تقسیم می کند و هدف اصلی آن جدایی توسعه رابط کاربری و UI نرم افزار از منطق آن و یا Backend است به طوری که رابط کاربری هیچ وابستگی ای به چیستی Backend و یا زبان آن نداشته باشد. در این مفهوم و یا در حالت بزرگتر معماری، منظور از Model همان لایه داده است و هر چیزی که به آن مربوط می شود. مانند API و یا Database. دقت داشته باشید که به این لایه میتوان repository‌ هم گفت چرا که محلی ست که تمام فعالیت های مرتبط به اطلاعات از قبیل ذخیره و خواندن در آن اتفاق میفتد. منظور از View همان رابط کاربری و یا ظاهر نرم افزار است و لایه سوم که ViewModel خوانده می شود نقشی ارتباطی میان آنها دارد. این لایه به نوعی یک تبدیل کننده است و کار آن تبدیل اطلاعات خروجی Model است به صورتی که به راحتی مدیریت شده و نمایش داده شوند. به این شکل نگاه کنید. منبع آب میتواند همان repository باشد و آب داخل آن همان داده یا اطلاعات. ما آب را از تانک میگیریم و به آشپرخانه می بریم که میتواند همان viewModel باشد. در آنجا یک تصفیه آب قرار دارد که آب را تصفیه کرده و قابل استفاده برای کاربر می کند. این همان View‌ است. در این معماری اضافه، حذف و یا تغییر یک عملکرد راحت تر است چرا که لایه ها جدایی خوبی دارند. مخصوصا که لایه Backend جدایی خوبی از لایه frontend دارد و همچنین با تغییرات منطق برنامه میدانیم که لایه ظاهری آن دچار آسیب نمی شود و همینطور میتوان تست های راحت تر و بهتری برای هر بخش نوشت.۵) مفهوم Micro-Frontendدر سال های اخیر و با گسترش استفاده از میکروسرویس ها که برای backend و توسعه سرویس ها به کار می رود ایده استفاده از چنین سبک توسعه ای به دیگر بخش ها نیز راه پیدا کرد. همچنین مشکلات کار به سبک مونولیتیک بر روی فرانت اند باعث شد بیشتر از قبل نیاز به چندگانگی این تکنولوژی و تقسیم آن به سبک بک اند احساس شود. اما میکروفرانت اند چیست؟‌طراحی و توسعه فرانت اند به سبکی که شامل تکه های کوچک قابل پیاده سازی، دیپلوی و تست مستقل باشد و جامعیت آنها بتواند یک رابط کاربری و یا یک UI را تشکیل دهد را میکرو فرانت اند می گویند. مزایای این روش را میتوان در چند مورد به صورت خلاصه بیان کردکدهای قابل تغییر و تعمیر کوچک ترتوسعه راحت تر مخصوصا در زمانی که پروژه به سمت بزرگتر یا scaling می روداما در کنار اینها میتواند به دانلود بیشتر بایت و یا duplication در کد نیز منجر شود.بیشتر مفاهیم میکروفرانت اند همانند میکروسرویس ها توسعه پیدا کرده و عرضه شده است اما نکته مهم در این زمینه این است که به آن صورت که باید و شاید فریمورک ها و یا منابعی برای توسعه جدی به این سبک به وجود نیامده و میتوان گفت جامعه توسعه دهندگان هنوز در حال توسعه این روش می باشد. بالاخره باید در نظر گرفت که این روش در سال ۲۰۱۶ تازه موجودیت پیدا کرد. بیشتر تمرکز و دلیل وجود ایده میکرفرانت اند، همانطور که در شکل نیز میتوان دید، دیپلوی جداگانه کامپوننت ها و یا قسمت های مختلف فرانت می باشد که میتواند به توسعه سریعتر و دقیقتر منجر شود. تصور کنید که دیگر نیاز نیست برای تغییرات یک بخش کوچک در سایت تمام پروژه را بیلد بگیرید و نسخه ای از آن تهیه کنید. برای مطالعه بیشتر ولی نه خیلی مفصل : لینکبرای در آوردن ته توی همه چیز :‌ لینک ۶)‌ مفهوم Api Gatewayبه طور خلاصه میتوان API GW یک ابزار مدیریت API ها معرفی کرد که میان کاربر و سرویس های بک اند می نشیند. اما کار آن چیست؟ خب API GW فراخوانی های انجام شده را دریافت می کند،‌ پاسخ سرویس های مورد نیاز برای پاسخ به فراخوانی را جمع می کند و در نهایت در قالبی مناسب کاربر، آن را برمیگرداند. اما اصلا استفاده از API GW به زحمتش می ارزد؟خب بیاید کمی از مشکلاتی که در نبود آن ایجاد می شود صحبت کنیم. در قدم اول باید توجه داشت که اگر فراخوانی های سرویس های شما به راحتی و توسط آدرس خودشان قابل استفاده باشند، شما تمام بک اند خود را در معرض عموم گذاشته اید و به راحتی میتوان آنها را از کار انداخت و یا در سامانه اخلال ایجاد کرد. از طرفی دیگر چطور میتوانید محدودیت فراخوانی روی آن بگذارید و یا به افراد مشخصی فقط اجازه فراخوانی بدهید؟ شاید بگویید به راحتی میتوان در بک اند یک سیستم لاگین پیاده سازی کرد. اما باید توجه داشته باشید که با این کار باز هم بار اضافی روی سرویس خواهید انداخت چرا که درخواست فرد باز هم به سرویس های شما خواهد رسید. مسئله بعدی تغییر آدرس و یا اضافه کردن API های جدید و از کار انداختن قدیمی هاست. شما طبیعتا دوست ندارید با هر تغییر آدرسی که به هر دلیلی اتفاق می افتد(مثلا تغییر سرور)، به مشتری آدرس جدید بدهید. این کار به کسب و کار شما آسیب میزند. شما همواره باید مشتری را از پیچیدگی سرویس های زیرساختی و بک اندی دور نگه دارید و API GW یکی از بهترین راه های این کار است. عملکرد آن در این مورد به خوبی شبیه به یک Revearse proxy است اما با قدرت بیشتر.یک مورد مهم دیگر که شاید اغلب به آن توجهی نمی شود. اگر کسب و کار شما و یا سرویس های شما زیاد فراخوانی شوند و یا بخواهید درکی از نحوه کارکرد سیستم های خود داشته باشید نیاز به مانیتورینگ دارید. این قدم اول درک و پایداری یک سیستم نرم افزاری ست. فرض کنید API GW وجود ندارد و شما بر روی هر سرویس خود یک سیستم مانیتورینگ بالا آوردید و اطلاعات لازم را میگیرید. خب آیا این مشکل شما را حل می کند؟ فرض کنید صد یا حتی پانصد API یا حتی سرویس دارید. چکار میکنید؟ برای هر کدام یک پنل جدا و یک مانیتورینگ جدا؟ چطور اینها را با هم جمع می کنید تا به یک درک کلی از عملکرد سیستم برسید؟ اینجاست که وجود یک لایه میانی بسیار به درد شما می خورد. تمام داده های مانیتورینگ را جمع می کند و به شما یک دید کلی می دهد. سیستم های تایید صلاحیت را روی آن بگذارید و مطمئن شوید که بار اضافی روی سرویس های شما قرار نمی گیرد. آدرس سرویس های بک اند خود را از طریق آن مخفی نگه دارید و حالا دیگر از نظر امنیت نیز خیال تان راحت باشد(البته این فقط یک قدم ساده در مسئله امنیت است) یکی از ابزارهای خیلی مهم در این زمینه Kong است. در این مقاله قرار نیست به سراغ پیاده سازی و جزئیات این ابزار بروم ولی توصیه می کنم بر روی سیستم خود به راحتی و با استفاده از Docker یک Kong بالا بیاورید و با آن کار کنید. کار کردن با آن ساده ست :) برای مطالب بیشتر و آشنایی بهتر :‌ لینکبرای راه اندازی و کار با Kong : لینک۷)‌ مفهوم BPMSمجموعه اقدامات و فعالیت‌هایی که هر سازمان و کسب و کاری به اجرا در می‌آورد تا به اهداف مشخص شده دست پیدا کند، تحت عنوان فرایند کسب و کار شناخته می‌شود. نرم‌افزار بی پی ام یا همان ‌BPMS یک ابزار اتوماسیون فرایند است. این ابزار کمک میکند تا فرایندهای هر روزه بررسی شود تا مشکلات و گلوگاه های موجود شناسایی شوند، هزینه های شرکت مدیریت شود و به طور کلی تا حد ممکن فرایندهای سازمان و افراد بهینه شوند. BMPSدر پیگیری، اجرا و خودکارسازی برخی عناصر فرایندهای کسب و کار نیز نقش دارد. این ابزار به عنوان یک سیستم شرکتی جهت ادغام اپلیکیشن‌ها، کارها و داده‌ها و ادغام جریان داده‌ها و تسک‌ها بین تیم‌ها و دپارتمان‌ها آغاز به کار کرد.این یک شمای ساده از فرایند اجرای این نرم افزارها را مشاهده می کنید. همانطور که از عکس پیداست به طور کلی میتوان این سبک نرم افزارها را ۵ قسمت تقسیم کرد. در قسمت طراحی تحلیلگران بیزنسی ابتدا اصول و قواعد کسب و کار موجود را بررسی می‌کنند، با ذینفعان مختلف مصاحبه می‌کنند و خروجی‌های موردنظر خود را با مدیریت به بحث می‌گذارند. هدف مرحله طراحی فرایند، دستیابی به فهمی از قواعد کار است. در قسمت مدلسازی، شناسایی، تعریف و بازنمایی فرایندهای جدید جهت پشتیبانی از قواعد کاری موجود برای ذینفعان مختلف اتفاق می افتددر قسمت اجرا فرایندهای کسب و کار ابتدا با گروه کوچکی از کاربران تست می‌شود، سپس به همه کاربران ارائه می‌شود.قسمت نظارت شامل تعیین شاخص‌های کلیدی عملکرد (KPI) و تصمیم گیری بر اساس آنها با استفاده از گزارش‌ها یا داشبوردهااما قسمت بهینه سازی. در این قسمت با وجود یک سیستم گزارش‌گیری کارآمد، سازمان می‌تواند عملیات را به طور موثری به سمت بهینه‌سازی یا بهبود فرایند، هدایت کند.اطلاعات بیشتر و کامل تر و حسابی مفصل تر :‌لینک۸) مفهوم صف یا message queueصف پیام این امکان را برای برنامه‌ها فراهم می‌کند که به صورت غیر همزمان با ارسال پیام‌ها از طریق یک صف با همدیگر ارتباط برقرار کنند. یک صف پیام، ذخیره‌سازی موقتی بین فرستنده و گیرنده فراهم می‌کند تا فرستنده بتواند بدون وقفه به کار خود در زمانی که برنامه مقصد مشغول است یا متصل نیست، ادامه دهد. متنی که بالا خواندید یک تعریف کلی از مفهوم صف بود. اما دقیقا صف چه کاری انجام می دهد؟ فرض کنید یک سرویس شما باید به تعدادی پیام جواب بدهد و هر پیام مدتی طول می کشد. وقتی یک درخواست برایش می آید یا میتواند آن را پردازش کند و یا نمیتواند. اگر بتواند که همه چیز خوب است اما اگر نشد و سرویس در حال پردازش پیام دیگری بود چه؟‌ درخواست از بین برود؟ یا پیامی به مشتری نمایش داده شود که بعدا امتحان کنید؟ هر دوی این روش ها کاربردی نیستند و باعث عملکرد ضعیف یک سیستم می شوند مخصوصا اگر سیستم ما دارای سرویس های پر کاربر باشد(یک اپراتور تلفن همراه را تصور کنید). در این شرایط پای صف به میان می آید. صف پیام هایی که باید منتظر بمانند را نگه می دارد و مانع از بهم ریختگی و یا گم شدن آنها می شود. در سیستم های service oriented و microservice صف از نان شب هم واجب تر است. مطالعه بیشتر : لینکآشنایی با یکی از بهترین ابزارهای صف یعنی rabbit mq :‌ لینک۹)‌ معماری ESB مجموعه ای از قوانین و اصول برای ادغام برنامه های کاربردی متعدد با هم بر روی یک زیرساخت اتوبوس مانند را ESB می گوییم. مفهوم اصلی معماری ESB این است که شما برنامه های مختلف را با قرار دادن یک گذرگاه ارتباطی بین آنها یکپارچه می کنید و سپس هر برنامه را قادر می سازید تا با این گذرگاه صحبت کند.حتی سرویس ها از طریق این گذرگاه با همدیگر صحبت کرده و اطلاعات مورد نیاز خود را بگیرند. گاهی حتی پیش می آید که دو سرویس که نیاز به یکدیگر دارند با پروتکل های متفاوتی ارتباط می گیرند. به عنوان مثال یکی با SOAP و دیگری با REST. وظیفه این درگاه ارتباطی در اینجا تبدیل زبان هر دو سرویس به یک زبان مشترک در داخل خود و پاسخگویی متناسب با پروتکل هر کدام می باشد. مفهوم ESB به دلیل نیاز به دور شدن از یکپارچگی نقطه به نقطه متولد شد که مدیریت آن در طول زمان شکننده و سخت می شود. ادغام نقطه به نقطه منجر به پخش کد در بین برنامه ها بدون هیچ راه مرکزی برای نظارت یا عیب یابی می شود. به زبان دیگر نمی شود به این راحتی درک کلی از سامانه و عملکرد آن پیدا کرد که طبیعتا این مسئله آسیب جدی به بزرگ شدن نرم افزار می زند.اگر کمی دقت کنید شباهت های زیادی میان ESB و API GW‌ می بینید. در حقیقت این دو تا حدی شبیه بهم عمل می کنند و حتی در بعضی سامانه ها از هر دو استفاده می شود. در حقیقت باید توجه داشت که API GW یک لایه پروکسی مانند است که وظیفه مدیریت و هندلینگ سیستم را دارد اما ESB شامل منطق نرم افزار شما نیز می شود. مسئله بعدی این است که در ESB مسیر تعامل سرویس ها با هم دو طرفه بوده و هر کدام میتواند به دیگری درخواست بدهد اما در API GW این مسیر یک طرفه بوده و سامانه ما شامل یک تامین کننده و یک مصرف کننده است. در حال حاضر روشی که کاربرد بسیار دارد استفاده از هر دوی این روش هاست. با وجود تکنولوژی های بهتر و دقیق تر سامانه برای دستیابی به پایداری بیشتر یک API GW در مسیر ورودی به ESB قرار می دهند و سرویس هایی همانند AUTH را بر روی آن می گذارند. و یک توصیه از طرف خودم که بیشتر از یک سال با ESB کار کردم. حتما تا جای ممکن آن را سبک کنید و تسک های اعتبارسنجی و این سبک کار ها را به API GW بسپارید.برای مطالعه بیشتر: لینک