Mohammad Teimori Pabandi
Mohammad Teimori Pabandi
خواندن ۳ دقیقه·۱ سال پیش

راهبردهای طراحی نرم‌افزار حسابداری با تمرکز بر «همیان» - بخش دوم: الگوی نامه‌ی اعمال

در این پست می‌خوام در خصوص یک الگوی دیگه صحبت کنم که خیلی جاها تکرار می‌شه؛ از دین تا مهندسی نرم‌افزار و حسابداری. تصمیم گرفتم بهش بگم «الگوی نامه‌ی اعمال» و جلوتر توضیح می‌دم چرا این اسم رو براش انتخاب کردم.

به طور کلی یه سری «چیز» داریم که حاصل‌جمع هستن؛

  • موجودیِ حساب: جمعِ تراکنش‌های ورودی و خروجی.
  • وضعیتِ فایل در git: جمعِ commit هاست.
  • وضعیتِ فعلیِ یک فایلِ فتوشاپ: حاصلِ تعدادی عملیات در این برنامه است (می‌تونید با undo مسیرش رو تا اول عقب‌عقب برید و این موضوع رو ببینید).
  • وضعیتِ فعلیِ دیتابیس: مثلاً در دیتابیسِ Postgres یک سری فایل داریم به نام wal که وضعیتِ دیتابیس از طریقِ پخشِ پشت‌سرهمِ اون فایل‌ها به دست می‌آد.
  • بلاکچین: از طریقِ پخشِ پشت‌سرهمِ تراکنش‌ها روی وضعیتِ اولیه، به وضعیتِ فعلی‌ش می‌تونیم برسیم.
  • شخصیت انسان (طبق نگاه استفان کاوی): حاصل‌جمع «اعمال» ماست. این‌که کی هستیم جمعِ همه‌ی کارهاییه که از نقطه‌ی اول کردیم (نامه‌ی اعمال به مثابه git و شخصیت ما به مثابه file).

خیلی مفاهیم و چیزها رو در جهان می‌شه از پشتِ این عینک دید و این لیست رو می‌شه زیاد ادامه داد، ولی برای این بحثمون، این مثال‌ها رو آوردم تا بعدش بگم همه‌ی این موارد دو مفهومِ تشکیل‌دهنده دارن:

  1. یک متغیر read-only که به صورت مستقیم تغییر نمی‌کنه و یک حاصل‌جمعه: مثلِ موجودی، وضعیتِ دیتابیس و شخصیتِ انسان. مثلاً دسترسی نداری که همین‌طوری دست ببری توی شخصیتت و از فردا صبح یک‌هو آدمِ با تمرکزی بشی.
  2. یک اهرم که وقتی می‌خوای با اون متغیر read-only تعامل کنی و تغییرات روش بدی، این اهرم رو در دست داری و هر کاری می‌کنی باید با همین اهرمت انجام بدی. مثلاً می‌تونی با هر روز مراقبه‌کردن شخصیتت رو به سمتِ یک شخصیتِ با تمرکز هُل بدی.
یک متغیر داریم که مستقیماً امکانِ ویرایشش وجود نداره، اما به واسطه‌ی یک اهرم می‌تونیم تغییراتمون رو به اون متغیر هُل بدیم.

این الگو رو در پیاده‌سازی میکروسرویس‌ها با نام Event Sourcing می‌شناسن:

  • The application reconstructs an entity’s current state (متغیر) by replaying the events (اهرم).

یعنی اتفاقاتی که برای یک موجودیت می‌افته رو لیست می‌کنن، و هر سیستم می‌آد اون اتفاقات رو پشت سر هم پخش می‌کنه و وضعیت نهایی رو می‌سازه. این‌طوری ضمنِ این‌که همه در وضعیتِ نهایی با هم اشتراک‌نظر دارن، مسیرِ رسیدن به اون وضعیت هم کاملاً مشخصه و می‌شه در هر نقطه از زمان، فهمید که وضعیتِ موجودیتمون به چه شکل بوده.

برای مثال فکر کنید موجودیتمون «موجودی جیبمون» ـه و می‌خوایم از طریق یه سری تراکنش بهش برسیم. این لیست رو در نظر بگیرید:

برای راحتی کار فقط دارم موجودیِ جیبِ خودم رو حسابداری می‌کنم و اصلِ پایستگی ارزش رو فعلاً بی‌خیال شدم
برای راحتی کار فقط دارم موجودیِ جیبِ خودم رو حسابداری می‌کنم و اصلِ پایستگی ارزش رو فعلاً بی‌خیال شدم

حالا اگه یک وضعیتِ اولیه در نظر بگیریم (در ۱۹ آبان موجودی جیبم ۰ بوده)، می‌تونیم با بازپخش تراکنش‌هامون، به وضعیتِ نهایی برسیم.

در نتیجه من در ۳۱ آبان موجودیِ جیبم می‌شه:

  • balance = +2000 -100 -400 +100

اما ویژگیِ خوبِ دیگه‌ی این روش، اینه که در هر نقطه از زمان هم می‌تونم موجودی رو محاسبه کنم

  • balance(t=start of 21 Aban) = +2000
  • balance(t=start of 22 Aban) = +2000 -100
  • balance(t=start of 23 Aban) = +2000 -100
  • balance(t=start of 24 Aban) = +2000 -100 -400
  • balance(t=start of 25 Aban) = +2000 -100 -400
  • ...
بخشی از تراکنش‌ها به صورت خط زمانی
بخشی از تراکنش‌ها به صورت خط زمانی



حالا که با این الگو بیشتر آشنا شدیم، می‌خوام دوباره تأکید کنم که مقدار «موجودی» در یک حساب بانکی، یک حاصل‌جمعه. حاصل‌جمعی که نمی‌شه مستقیماً بهش دست زد و ویرایشش کرد و باید از «اهرم» ویژه‌ی اون استفاده کنیم تا موجودی رو عوض کنیم. برای «موجودی»، این اهرم می‌شه همون «تراکنش» که جلوتر در موردش بیشتر صحبت خواهیم کرد.

در نتیجه توی طراحی نرم‌افزارمون، باید این رو لحاظ کنیم که هیچ‌کس نتونه مستقیماً به مقدار موجودی دست بزنه. با این مقدار باید به شکل فقط‌خواندنی(read-only) رفتار بشه و تنها چیزی که می‌تونه تغییرش بده، باید تراکنش باشه.

مطالعه‌ی بیشتر:

https://martinfowler.com/eaaDev/EventSourcing.html#EventsAndAccounts

https://www.youtube.com/watch?v=ck7t592bvBg

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