علی پیرپیران
علی پیرپیران
خواندن ۷ دقیقه·۱ سال پیش

برخی مفاهیم پرکاربرد و جدید در معماری نرم‌افزار

هدف این مطلب، کسب دانشی اولیه و سطحی درباره چندین موضوع متنوع و پراکنده است.


Modular Monolithic

یکی از انواع معماری‌های یکپارچه(monolithic) است. در این روش، تقسیم‌بندی کد پروژه بر اساس دامنه موضوعات است. بر خلاف معماری لایه لایه که در آنجا تقسیم بندی نرم‌افزار به صورت تکنیکال انجام می‌گرفت.

مانند باقی معماری های یکپارچه، خروجی یک فایل قابل اجرا است. وجود یک فایل برای اجرای برنامه به استقرار ساده نرم‌افزار کمک کرده و مزیت آن محسوب می‌شود.
برخلاف معماری میکرو سرویس، تمام پروژه باید با یک زبان برنامه نویسی، نوشته شود که این می‌تواند عیب تلقی شود.

در زمان ایجاد تیم، نیاز است که برای جنبه های متفاوت فنی یک فرد متخصص در تیم وجود داشته باشد. در ادامه مزیت این کار گفته می‌شود.

به طور معمول در نرم‌افزار تغییرات مربوط به یک دامنه خاص هستند. برای مثال تغییر در بخش خرید محصول. بنابراین در این نوع معماری، تمام کار مورد نیاز برای یک تغییر، به یک تیم مشخص مربوط می‌شود که این مزیت محسوب می‌شود.

برخی از عیوب این نوع معماری:
- در صورت رخ دادن یک خطا در یک ماژول، کل سیستم با مشکل مواجه می‌شود.
- تغییر مقیاس نرم‌افزار کار سختی است.


AWS

یک سرویس ابری است که توسط آمازون ایجاد شده است. به کمک دیتاسنترهای آمازون در سراسر جهان خدمات ارائه می‌کند.
این سرویس‌ها شامل پردازش، ذخیره‌سازی، پایگاه داده و ... است.

برای کمپانی‌هایی که نیاز دارند با هزینه کم شروع به کار کنند گزینه خیلی خوبی است به دلیل اینکه نیاز به پرداخت هزینه های زیاد برای تهیه زیرساخت مناسب ندارند و تنها بر حسب میزان استفاده از سرویس های aws هزینه پرداخت می‌کنند (pay as you go).


API First Approach

در این روش، طراحی APIها قدم اول ساخت نرم‌افزار است. یعنی ابتدا API ایجاد می‌شود سپس کد باقی قسمت‌ها زده می‌شود.
برای این منظور نیاز است که API های داخل(private) و خارجی(public) مشخص شوند.

با ایجاد API، راه ارتباطی برای کاربران، برنامه نویسان و سرویس های خارجی مشخص می‌شود. این کار به توسعه و تست ساده‌تر و زودتر نرم‌افزار کمک می‌کند.


No SQL Databases

این نوع پایگاه‌های داده سخت‌گیری های پایگاه داده های رابطه‌ای را ندارند. در نتیجه:

  • منعطف هستند
  • کمک می‌کنند به توسعه سریع
  • استفاده راحتی دارند
  • برای مقیاس‌های بزرگ، حجم بالای اطلاعات با زمان دسترسی پایین مناسب هستند.

برخلاف پایگاه داده های رابطه‌ای، نیاز به تعریف schema برای جداول نیست. بنابراین، چک کردن کلیدها(خارجی، اصلی و ...) را ندارد که به سرعت و سادگی آن‌ها کمک می‌کند. معمولا هر رکورد داده را به صورت json ذخیره می‌کنند.

انواع پایگاه داده‌های No SQL

  • کلید/مقدار (key/value)
    - ذخیره در Ram مانند Redis
    - ذخیره در Disk مانند Couchbase
  • گرافی (Graph based) مانند Neo4j
  • داکیومنتی (Document oriented) مانند MongoDB
  • سطونی (Column oriented) مانند Cassandra

Serverless Architecture

در این معماری، کاربر نیازی به تهیه زیر‌ساخت(حافظه، مموری، پردازنده و ...) ندارد. تنها نیاز است که بدنه فانکشن و رویداد(Event) مربوطه را تعیین کند. منظور از رویداد، رخدادی است که با آن، فانشکن باید اجرا شود.
یک نمونه معروف آن، Function As A Service (FAAS) است.

چند مثال از انواع رویداد

  • آدرس های وب سرویس رست (Rest Webservice)
    https://<gateway URL>:<port>/function/<function name>
  • کلیک کاربر داخل مرورگر
  • رویدادی از سمت یک حسگر، مثلا تغییر دمای محیط

مزیت اصلی این معماری، کاهش هزینه است. چون استفاده کنندگان تنها هزینه اجرای فانشکن را پرداخت می‌کنند. برای مثال نیاز به تهیه زیرساخت کامل برای فانکشنی که به ندرت اجرا می‌شود نیست (هزینه زمان بیکاری سرور پرداخت نمی‌شود!)



Domain Driven Design

طراحی Domain Driven یا به اختصار DDD، یک رویکرد طراحی نرم‌افزار است که سال ۲۰۰۴ معرفی شد. یک رویکرد طراحی از بالا به پایین است. معرفی چند مفهوم به کار رفته در این معماری:

دامنه(Domain)
منظور از دامنه در توسعه نرم افزار، مفاهیم مرتبط با کسب و کار است. مفاهیمی که نرم افزار قرار است آن هارا پیاده سازی کند.

معماری Domain Driven
در طراحی نرم افزار، برای کاربر نهائی، تفاوتی ندارد که از کدام تکنولوژی‌ها یا زبان برنامه‌نویسی استفاده کرده‌ایم یا اینکه چقدر معماری تمیزی داشته‌ایم. باید در حین توسعه، علاوه بر دید تکنولوژی، از دید کاربر نهائی هم به مسئله نگاه کنیم.

"It’s not the customer’s job to know what they want" - Steve Jobs
فهم نیاز کاربران، وظیفه آن‌ها نیست

معماری Domain Driven دو ابزار طراحی را معرفی ‌میکند:
۱- طراحی راهبردی (Strategic design)
۲- طراحی تاکتیکی (Tactical Design)

طراحی راهبردی به ما کمک میکند تا مسئله را به دید مدل‌ها نگاه کنیم و حل کنیم. مشابه طراحی شی گرا. چند مفهوم مورد استفاده در طراحی راهبردی:

۱. مدل - Model
تکه کد یا مستندی است که به منطق های اصلی و پایه‌ای نرم افزار مربوط می‌شود.

۲. یکپارچگی زبان (Ubiquitous language)
یک زبان مشترک بین اعضای تیم برای برقراری ارتباط بین فعالیت‌ها و مدل دامنه.

۳. محدوده‌ی مفاهیم (Bounded Contexts)
در توسعه به مرور ممکن است یک مدل بزرگ شود و نیاز به شکستن آن باشد، این مفهوم، یک سری توصیفات برای ایجاد مرزبندی میان مدل‌ها است.


طراحی تاکتیکی (Tactical Design)
درباره مسائل فنی و مربوط به پیاده سازی صحبت می کند.چیزهایی مثل سرویس‌ها، entities، repositories و factories.


Hexagonal architecture


این معماری ساختار مشخصی برای جداسازی بین اپلیکیشن و اجزای مرتبط با اپلیکیشن تعیین می‌کند. منظور از اجزای مرتبط، استفاده کنندگان (Driving Side) و استفاده شونده‌ها (Driven Side) است.
دو مفهوم به کار رفته در این معماری پورت(Post) و آداپتور(Adapter) هستند. در ادامه هرکدام از این واژه‌ها توضیح داده می‌شوند.

پورت (Port)
پورت‌ها در مرز ما بین اپلیکیشن و اجزای مرتبط قرار می‌گیرند. آن‌ها یک قالب مشخصی را تعیین می‌کنند برای ارتباطات. چه ارتباط اپلیکیشن با اجزای خارجی مانند پایگاه داده و یا ارتباط اجزای خارجی با اپلیکیشن مانند استفاده‌کنندگان از این سرویس.

آداپتور (Adapter)
آداپتور، وسیله ارتباط با اپلیکشن هستند به وسیله پورت ها. در واقع یک آداپتور، رابط پورت را پیاده سازی می‌کنند تا اپلیکیشن بتواند از آن‌ها استفاده کنند و یا اینکه با توجه به رابط اپلیکیشن، با اپلیکیشن ارتباط برقرار می‌کند.

استفاده کنندگان(Driving Side) و استفاده شونده‌ها (Driven Side)
ارتباطات بین اپلیکیشن و محیط بیرون دو نوع هستند.

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

پیاده‌سازی
در پیاده‌سازی این معماری:

  • پورت‌ها معمولا به صورت interface تعریف می‌شوند.
  • آداپتور های استفاده کننده، از یک پورت استفاده می کنند و اپلیکیشن نیز سرویس خود را با توجه به interface تعریف شده توسط پورت پیاده سازی کرده است.
  • آداپتور های مورد استفاده توسط اپلیکیشن، interface یک پورت را پیاده سازی می‌کنند و سرویس اپلیکیشن از آن آداپتور استفاده می‌کنند.

در هردو حالت پورت‌ها داخل فضای اپلیکیشن هستند و آداپتورها در بیرون قرار می‌گیرند.



Event sourcing

معماری Event sourcing یک راهکار معماری نرم افزار که در آن حالت فعلی هیچ موجودیتی ذخیره نمی‌شود. بلکه حالت آن به وسیله تمامی رخدادهایی که برای آن موجودیت اتفاق افتاده است به دست می‌اید.

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

اجزای اصلی یک اپلیکیشن با معماری Event Sourcing:

  • موجودیت‌ها (Entities)
    یک موجودیت مرتبط با یک دامنه خاص از نرم افزار است. تغییرات ان توسط رخدادها انجام می شود.
  • رخدادها (Events)
    اتفاقی است که برای یک موجودیت خاص اتفاق افتاده، حاوی نوع تغییر و زمان رخداد است.
  • انبار رخداد (Event Store)
    یک سرویس است که امکان افزودن رخداد مرتبط با یک موجودیت را فراهم میکند و همچنین دریافت لیست رخدادهای مرتبط با یک موجودیت.



منابع


معماریبرنامه نویسیشروع کارمعماری نرم افزارmicroservice
شاید از این پست‌ها خوشتان بیاید