TG Telegram Group Link
Channel: Agile Software Architecture-Microservices
Back to Bottom
Please open Telegram to view this post
VIEW IN TELEGRAM
📌 چهار ضلع طراحی نرم‌افزار: زبان، مدل، متخصصان دامنه، و کد

وقتی از طراحی نرم‌افزار حرف می‌زنیم، خیلی‌ها سریع می‌رن سراغ معماری، فریم‌ورک، یا ساختارهای کدی. ولی اصل ماجرا از یه جای دیگه شروع می‌شه: مدل. مدلی که قراره بین آدم‌ها و کد یه پل بزنه، و ریشه‌ش توی دنیای واقعی باشه.
تو رویکرد DDD، مدل فقط یه دیاگرام نیست؛ یه گفت‌وگوی زنده‌ست، یه ابزار برای درک و بازنمایی مسئله — نه صرفاً راه‌حل.

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

💬 مدل‌سازی یه فرایند لحظه‌ای نیست، یه مسیر تدریجیه. وسط گفت‌وگوها شکل می‌گیره، توی برخورد با واقعیت‌ها اصلاح می‌شه، و دائم در حال تغییره. یک فرآیند Just-In-Time

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

♻️ این تعامل بین چهار ضلع طراحی نرم‌افزار — زبان، مدل، متخصصان دامنه و کد — یه چرخه‌ی بازخورد دائمی می‌سازه. چرخه‌ای که باعث می‌شه نرم‌افزار هم دقیق‌تر بشه، هم قابل نگهداری‌تر، و هم واقعاً به درد بخور.

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


http://domaindrivendesign.ir/the-four-angles-of-software-design/
Please open Telegram to view this post
VIEW IN TELEGRAM
🚀مقایسه Exploratory Domain Discovery با EventStorming و Domain Story Telling


از چت جی‌پی‌تی پرسیدم که Exploratory Domain Discovery رو با دو رویکرد متداول و شناخته شده‌ی دیگر یعنی EventStorming و Domain Story Telling مقایسه کند.


https://exploratorydomaindiscovery.com/
🔍 معرفی مختصر Exploratory Domain Discovery (EDD)

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

این رویکرد، ریشه در تفکر سیستماتیک و روایت‌محور دارد. درست مثل یک فیلم یا رمان که همه‌ی اتفاقات برای انتقال یک پیام اصلی طراحی شده‌اند، در دامنه‌ی یک نرم‌افزار هم بیشتر اجزای سیستم در خدمت یک «مفهوم کلیدی» یا همان Main Point هستند؛ چیزی که بدون آن، کل ساختار بی‌معنا می‌شود. در EDD ما تلاش می‌کنیم این نقطه‌ی مرکزی را پیدا کرده و روابط علّی و ساختارهای اطراف آن را کشف کنیم.

🌀 فرآیند اکتشاف در EDD به‌صورت چرخشی (Iterative) و عرضی (Breadth-First) انجام می‌شود. فرض کنید Main Point در مرکز یک‌سری دایره‌ی هم‌مرکز قرار دارد. در دور اول، تصویری کلی و انتزاعی از دامنه ساخته می‌شود. در دورهای بعدی، این دایره تنگ‌تر شده و وارد جزئیات بیشتری می‌شویم. این مدل‌سازی لایه‌لایه، کمک می‌کند پیچیدگی‌ها را بهتر درک کرده و رفتارهای تکرارشونده را بشناسیم.

یکی از ویژگی‌های کلیدی EDD، روایت معکوس (Backward Storytelling) است — یعنی به‌جای اینکه با «از کجا شروع کنیم؟» آغاز کنیم، می‌پرسیم: «ته داستان چیست؟». این دیدگاه باعث می‌شود روابط علت و معلولی واضح‌تر و دقیق‌تر دیده شوند.


🧩 در EDD ما با سه ابزار اصلی کار می‌کنیم:

🟦 مفهوم Domain Concept: هر مفهوم کلیدی که در دامنه وجود دارد را روی یک کارت می‌نویسیم.

🔄 مفهوم Relation : رابطه‌ی بین این مفاهیم را مشخص می‌کنیم، از انتها به ابتدا.

📝 مفهوم Example : برای هر مفهوم، یک نمونه واقعی و قابل لمس می‌نویسیم تا فهم مشترک بین افراد تیم شکل بگیرد.

🎯 مثال کاربردی:

فرض کنید در حال تحلیل یک سیستم حقوق و دستمزد هستید.
از سؤال «ته داستان چیست؟» شروع می‌کنیم: مثلاً صدور فیش حقوقی خروجی نهایی است. آن را روی یک کارت مفهومی (domain concept) یادداشت می‌کنیم. سپس یک گام به عقب: فیش حقوقی حاصل محاسبه‌ی فرمول‌های حقوق است. این فرمول‌ها هم بر اساس کارکرد ماهانه‌ی کارمند محاسبه می‌شوند.
با همین روال، مفاهیم را از پایان به ابتدا کشف و یادداشت می‌کنیم. سپس روابط میان آن‌ها را (باز هم از انتها به ابتدا) ثبت می‌کنیم. در پایان، برای هر مفهوم یک مثال واقعی (concrete example) می‌نویسیم تا از درستی و شفافیت مدل اطمینان حاصل شود.

🧠 فلسفه‌ی EDD:

• بهره‌گیری از تفکر سیستماتیک و روایت‌محور
• تمرکز بر کشف تدریجی و دید کل‌نگر به دامنه
• مدل‌سازی چرخشی برای کشف رفتارهای تکرارشونده دامنه

🔁 الگوهای رایج (Patterns):

چرخه‌های زمانی مثل حقوق ماهیانه یا فرایند رزرو
مفهوم کلیدی (Main Point) که سایر اجزای دامنه حول آن شکل می‌گیرند
روایت معکوس برای کشف روابط علت و معلولی

در نهایت اینکه:
EDD ابزارهای ساده‌ای داره — مثل کارت‌های مفهومی و مثال — اما قدرتش در طرز فکر پشتشه: اینکه قبل از ورود به طراحی یا کدنویسی، دقیقاً بفهمیم چه چیزی را طراحی می‌کنیم و چرا.

📎 اطلاعات بیشتر:
https://exploratorydomaindiscovery.com

-انجمن DDD ایران
@DDD_Iran
Please open Telegram to view this post
VIEW IN TELEGRAM
Loop vs Recursion.pdf
330.4 KB
🎯 درک عمیق control flow یکی از پایه‌های اصلی برنامه‌نویسیه. در این مقاله به بررسی تفاوت‌های بین loop و recursion پرداختم و نشون دادم که چرا این انتخاب‌ها فراتر از syntax ساده هستن و به mental models ما برمی‌گردن.

اگه شما هم تجربه‌ای در این زمینه دارید یا سوالی براتون پیش اومده، حتماً تو کامنت‌ها باهام به اشتراک بذارید. خوشحال میشم نظر شما رو هم بدونم .
Please open Telegram to view this post
VIEW IN TELEGRAM
Agile Software Architecture-Microservices
پیش از مطالعه‌ی این مقاله، پیشنهاد می‌کنم نگاهی به مقاله‌ی پیشین با عنوان "Loop vs Recursion" بیندازید. این دو مقاله، بخشی از یک مجموعه‌ی مقالات مرتبط هستند و به‌زودی شماره‌ی سوم آن نیز منتشر خواهد شد. مشتاقانه منتظر دریافت نظرات شما هستم.
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
S3Pattern.pdf
426.2 KB
📝 State/Status Segregation (S3) Pattern
Making Systems More Predictable by Separating Lifecycle from Context

🔍 In complex systems, mixing up state and status often leads to bloated models, fragile logic, and unpredictable behavior.

This paper, written by Masoud Bahrami, introduces the State/Status Segregation (S3) pattern, a modeling principle that cleanly separates lifecycle control (state) from contextual signals and side conditions (status).

❇️ By applying S3, you can design systems with clearer APIs, more predictable behavior, and codebases that are easier to test, evolve, and reason about.
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
سلام به همه دوستان و عزیزانم

امیدوارم حال دل‌تون خوب باشه و در آرامش و سلامت باشید. این روزها در ایران شرایط خاصی رو سپری می‌کنیم و بیش از همیشه نیاز به هوشیاری و خونسردی داریم.

لطفاً مراقب خودتون و عزیزانتون باشید. آرزوی آرامش و سلامتی رو برای همه شما عزیزان دارم

به امید روزهایی پر از آرامش و بی‌دغدغه برای همه‌مون 🌿❤️
💡 Mixed Responsibility Smell

فرض کنید متدی دارید که پول را به حساب کاربر برمی‌گرداند و در همان لحظه مقدار جدید موجودی را هم برمی‌گرداند:
public Money Refund(Money amount)
{
Balance += amount;
return Balance;
}


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

اما سوال اینجاست:
آیا درسته که یک متد هم وضعیت را تغییر دهد و هم مقدار به‌روز شده رو برگرداند؟ در واقع سوال مهم در باره نحوه‌ی مدل کردن و پیاده‌سازی سناریوهایی که در بالا اشاره شد، است.

در جواب باید بگم:
این دقیقاً همون جاییه که با یک Code Smell به نام Mixed Responsibility Smell روبرو هستیم.

قطعاً ما نیاز به متد دیگری داریم که صرفاً موجودی را به ما بدهد. در واقع، نمی‌توانیم برای دریافت موجودی تنها به متد Refund تکیه کنیم؛ چرا که این امر ما را مجبور می‌کند برای هر بار خواندن موجودی، یک عملیات Refund انجام دهیم که نه منطقی است و نه قابل قبول. این یعنی عملاً ما هیچ‌گاه به یک موجودی ثابت و قابل اتکا دسترسی نداریم. علاوه بر بحث عدم قطعیت (indeterministic behavior) و موارد مشابه، این وضعیت یک Code Smell جدی محسوب می‌شود. حداقل پیامد آن این است که ما یک منطق یکسان (یعنی محاسبه موجودی) را در دو نقطه مختلف تکرار می‌کنیم: هم در متد Refund و هم در متدی مانند GetBalance، حتی اگر GetBalance تنها شامل return Balance; باشد.


سوال بعدی اینه که: چرا این مشکل‌ساز است
این «بوی بد» زمانی اتفاق می‌افته که یک متد یا کامپوننت بیش از یک مسئولیت یا وظیفه را بر عهده بگیره و باعث شود:

ابهام در نقش و وظیفه اصلی کد
پیچیدگی در فهم، تست و نگهداری کد
تکرار منطق مشابه در چند نقطه
مثل منطق محاسبه یا به‌روزرسانی موجودی که هم در متد Refund و هم در متد GetBalance تکرار می‌شود (حتی اگر در GetBalance صرفاً return Balance; باشد)
کاهش انعطاف‌پذیری و سختی توسعه کد
رفتار نامعین (Indeterministic Behavior): اگر برای گرفتن موجودی مجبور باشیم همیشه Refund را صدا بزنیم، هیچ‌وقت موجودی واقعی و پایدار در اختیار نخواهیم داشت، چون هر بار با گرفتن موجودی، وضعیت تغییر می‌کند!



مثال بهتر:
// command
public void Refund(Money amount)
{
Balance += amount;
}

// query
public Money GetBalance()
{
return Balance;
}


نتیجه اینکه:
هشدار مهمی که Mixed Responsibility Smell به ما میده اینه که:

یک متد یا کامپوننت باید تنها یک مسئولیت واضح و مشخص داشته باشد.
تفکیک درست مسئولیت‌ها باعث میشه که کد:
ساده‌تر و قابل فهم‌تر شود
راحت‌تر تست و نگهداری شود
توسعه و تغییرات آینده بدون دردسر انجام شود
Please open Telegram to view this post
VIEW IN TELEGRAM
HTML Embed Code:
2025/07/03 11:40:44
Back to Top