<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"><channel><title>نوشته های Amir Mokarchi</title><link>https://virgool.ir/feed/@mokarchi</link><description>A software engineer</description><language>fa</language><pubDate>2026-11-10 15:07:40</pubDate><image><url>https://files.virgool.ir/upload/users/8262/avatar/avatar.png</url><title>Amir Mokarchi</title><link>https://virgool.ir/@mokarchi</link></image><item><title>رشد کمتر، سودآوری بیشتر؛ اقتصاد جدید شرکت‌های فناوری</title><link>https://virgool.ir/@mokarchi/رشد-کمتر-سودآوری-بیشتر-اقتصاد-جدید-شرکت-های-فناوری-mg6bxhynlmw2</link><description>تحولات ناشی از هوش مصنوعی تنها به ظهور استارتاپ‌های جدید و تغییر الگوی رشد یونیکورن‌ها محدود نشده است. شرکت‌های فناوری که پیش از موج اخیر هوش مصنوعی شکل گرفته‌اند نیز با تغییرات مهمی در محیط سرمایه‌گذاری و اولویت‌های عملیاتی خود مواجه شده‌اند.ترکیب دو عامل، نقش مهمی در شکل‌گیری این وضعیت داشته است: تغییر جهت سرمایه‌گذاری خطرپذیر (Venture Capital) به سمت هوش مصنوعی و افزایش نرخ بهره که هزینه تأمین سرمایه را بالا برده است.در چنین شرایطی، بسیاری از شرکت‌های فناوری ناچار شده‌اند راهبردهایی را که پیش‌تر بر رشد سریع درآمد و گسترش سهم بازار متمرکز بودند، بازنگری کنند.داده‌های بانک سیلیکون‌ولی (SVB) نشان می‌دهند که از سه‌ماهه نخست سال ۲۰۲۲، شرکت‌های فناوری در تمام بخش‌های مورد بررسی، به‌تدریج از رشد سریع به هر قیمت فاصله گرفته و توجه بیشتری به کنترل هزینه‌ها، کاهش زیان و بهبود سودآوری نشان داده‌اند.نتیجه این تغییر، کاهش قابل‌توجه نرخ رشد درآمد در کنار بهبود حاشیه سود بوده است؛ تغییری که می‌توان از آن با عنوان «معاوضه رشد با سودآوری» یاد کرد.۱. چرا اولویت شرکت‌های فناوری تغییر کرد؟برای درک این تحول، ابتدا باید شرایط اقتصادی و سرمایه‌گذاری پیش از سال ۲۰۲۲ را در نظر گرفت.در دوره‌ای که نرخ بهره بسیار پایین بود و سرمایه خطرپذیر با سهولت بیشتری در اختیار استارتاپ‌ها قرار می‌گرفت، بسیاری از شرکت‌های فناوری رشد سریع را بر سودآوری کوتاه‌مدت ترجیح می‌دادند.در این الگو، شرکت‌ها می‌توانستند با اتکا به سرمایه جذب‌شده، هزینه‌های قابل‌توجهی را صرف توسعه محصول، استخدام نیرو، بازاریابی و ورود به بازارهای جدید کنند؛ حتی اگر فعالیت عملیاتی آن‌ها همچنان زیان‌ده بود.فرض اصلی این بود که رشد سریع درآمد و افزایش سهم بازار، در آینده به سودآوری و ارزش‌گذاری بالاتر منجر خواهد شد.اما از سال ۲۰۲۲، شرایط تغییر کرد.افزایش نرخ بهره، هزینه سرمایه را بالا برد و تأمین مالی جدید را دشوارتر کرد. هم‌زمان، گسترش هوش مصنوعی باعث شد بخش قابل‌توجهی از توجه و منابع سرمایه‌گذاران به شرکت‌ها و فرصت‌های جدید این حوزه معطوف شود.در نتیجه، بسیاری از شرکت‌های فناوری با محیطی مواجه شدند که در آن، اتکا به جذب سرمایه مستمر برای تأمین هزینه‌های عملیاتی دیگر به‌اندازه گذشته قابل‌اطمینان نبود.این تغییر، شرکت‌ها را به بازنگری در اولویت‌های خود سوق داد: کاهش هزینه‌ها، افزایش بهره‌وری، مدیریت دقیق‌تر نقدینگی و حرکت به سمت سودآوری اهمیت بیشتری پیدا کرد.۲. داده‌های SVB چه تغییری را نشان می‌دهند؟نمودار SVB، مسیر تغییر رشد درآمد و حاشیه سود شرکت‌های فناوری را از سه‌ماهه نخست ۲۰۲۲ تا سه‌ماهه دوم ۲۰۲۶ بررسی می‌کند.در این نمودار، محور افقی نشان‌دهنده میانه نرخ رشد سالانه درآمد است و از صفر تا ۸۰ درصد امتداد دارد.محور عمودی، میانه حاشیه سود را نشان می‌دهد و محدوده‌ای از منفی ۹۰ درصد تا صفر را پوشش می‌دهد.بنابراین، هرچه یک نقطه به سمت راست نمودار حرکت کند، نشان‌دهنده رشد درآمد بیشتر است. همچنین، حرکت آن به سمت بالا به معنای کاهش زیان و نزدیک‌تر شدن حاشیه سود به نقطه سربه‌سر است.چهار بخش اصلی در این بررسی حضور دارند: فناوری مالی (Fintech)، نرم‌افزار سازمانی (Enterprise)، فناوری‌های پیشرو (Frontier Tech) و اینترنت مصرف‌کننده (Consumer Internet).وضعیت اولیه در سه‌ماهه نخست ۲۰۲۲: رشد بالا همراه با زیان سنگیندر ابتدای دوره، بسیاری از شرکت‌های فناوری در سمت راست و پایین نمودار قرار داشتند.این موقعیت نشان می‌دهد که شرکت‌ها با وجود رشد سریع درآمد، همچنان حاشیه سود منفی قابل‌توجهی داشتند.برای مثال، در بخش فناوری‌های پیشرو، میانه رشد سالانه درآمد حدود ۵۷ درصد بود، در حالی که حاشیه سود به حدود منفی ۶۷ درصد می‌رسید.در بخش فناوری مالی نیز میانه رشد درآمد نزدیک به ۷۶ درصد و حاشیه سود حدود منفی ۵۵ درصد بود.این ارقام نشان‌دهنده الگویی هستند که در آن، رشد سریع کسب‌وکار با زیان‌دهی قابل‌توجه همراه بوده است.برای درک مفهوم حاشیه سود منفی، فرض کنید شرکتی ۱۰۰ میلیون دلار درآمد و حاشیه سود منفی ۵۵ درصد داشته باشد. در این حالت، زیان متناظر با تعریف سود مورد استفاده در گزارش، حدود ۵۵ میلیون دلار خواهد بود.البته نوع دقیق حاشیه سود اهمیت دارد. حاشیه سود خالص، حاشیه سود عملیاتی و حاشیه EBITDA تعدیل‌شده، شاخص‌های یکسانی نیستند و برای تفسیر حسابداری دقیق باید مشخص شود SVB از کدام تعریف استفاده کرده است.تغییر مسیر در سال‌های ۲۰۲۲ و ۲۰۲۳: کاهش هزینه‌ها برای مهار زیانبا تغییر شرایط تأمین مالی، شرکت‌ها به‌تدریج راهبردهای رشد پرهزینه را تعدیل کردند.کاهش استخدام، محدود کردن هزینه‌های بازاریابی، بازنگری در پروژه‌های توسعه‌ای و تمرکز بیشتر بر فعالیت‌های درآمدزا، از جمله اقداماتی هستند که می‌توانند در چنین شرایطی به بهبود وضعیت مالی شرکت‌ها کمک کنند.نمودار SVB نشان می‌دهد که در سال‌های ۲۰۲۲ و ۲۰۲۳، حرکت عمومی شرکت‌ها به سمت کاهش نرخ رشد درآمد و بهبود حاشیه سود بوده است.این تغییر در نمودار به‌صورت حرکت از ناحیه پایین و راست به سمت بالا و چپ دیده می‌شود.به بیان دیگر، شرکت‌ها بخشی از سرعت رشد خود را از دست داده‌اند، اما در مقابل، میزان زیان آن‌ها کاهش یافته است.این همان معاوضه‌ای است که در عنوان این بخش به آن اشاره می‌شود: پذیرش رشد کندتر در ازای بهبود وضعیت مالی و کاهش وابستگی به تأمین سرمایه جدید.وضعیت در سه‌ماهه دوم ۲۰۲۶: همگرایی بخش‌های مختلفدر پایان دوره بررسی‌شده، یعنی سه‌ماهه دوم ۲۰۲۶، هر چهار بخش در محدوده نسبتاً نزدیک‌تری از نمودار قرار گرفته‌اند.میانه نرخ رشد درآمد در بیشتر بخش‌ها به محدوده ۱۰ تا ۳۰ درصد رسیده و حاشیه‌های سود نیز عمدتاً بین منفی ۵ تا منفی ۳۰ درصد قرار گرفته‌اند.این وضعیت در مقایسه با ابتدای سال ۲۰۲۲، نشان‌دهنده کاهش قابل‌توجه نرخ رشد و بهبود چشمگیر حاشیه سود است.البته همه شرکت‌ها به نقطه سربه‌سر نرسیده‌اند. حاشیه سود منفی ۳۰ درصد همچنان نشان‌دهنده زیان‌دهی قابل‌توجه است، اما در مقایسه با حاشیه‌های منفی ۵۵ تا ۶۷ درصدی ابتدای دوره، بیانگر کاهش شدت زیان است.بنابراین، تعبیر دقیق‌تر این است که شرکت‌ها به سمت سودآوری حرکت کرده‌اند، نه اینکه الزاماً همگی سودآور شده باشند.۳. فناوری‌های پیشرو: مسیری متفاوت و پرنوساندر میان چهار بخش بررسی‌شده، فناوری‌های پیشرو (Frontier Tech) مسیر متفاوت‌تری را طی کرده‌اند.منحنی این بخش در نمودار، قوسی عمیق و تقریباً U شکل را تشکیل می‌دهد.در بخشی از دوره، میانه حاشیه سود شرکت‌های این گروه تا حدود منفی ۸۵ درصد کاهش یافته و نرخ رشد درآمد نیز به نزدیکی ۲۰ درصد رسیده است.این نقطه، ترکیبی از رشد نسبتاً محدود و زیان‌دهی بسیار شدید را نشان می‌دهد.با این حال، شرکت‌های این بخش در ادامه توانسته‌اند حاشیه سود خود را بهبود دهند و از عمیق‌ترین نقطه زیان فاصله بگیرند.این مسیر یادآور می‌شود که تغییر اولویت از رشد به سودآوری، لزوماً فرایندی سریع یا یکنواخت نیست. ممکن است شرکت‌ها پیش از مشاهده نتایج اقدامات اصلاحی، دوره‌ای از افت رشد و فشار مالی بیشتر را تجربه کنند.همچنین، تفاوت در ماهیت فناوری، هزینه‌های تحقیق و توسعه، نیاز سرمایه‌ای و زمان تجاری‌سازی محصولات می‌تواند باعث شود شرکت‌های بخش‌های مختلف مسیرهای متفاوتی را طی کنند.۴. استثنای مهم: شرکت‌هایی که اخیراً سرمایه جذب کرده‌اندیکی از نکات قابل‌توجه نمودار، وضعیت شرکت‌هایی است که به‌تازگی موفق به جذب سرمایه شده‌اند.SVB این شرکت‌ها را به‌عنوان کسب‌وکارهایی تعریف می‌کند که طی سه سه‌ماهه اخیر، یک دور تأمین مالی داشته‌اند.در نمودار، میانه عملکرد این گروه با مربع‌های توخالی مشخص شده است.برخلاف روند عمومی بازار، این شرکت‌ها همچنان در ناحیه رشد بالا و حاشیه سود عمیقاً منفی قرار دارند.میانه نرخ رشد درآمد آن‌ها در بخش‌های مختلف حدود ۶۰ تا ۷۵ درصد است، در حالی که حاشیه سودشان عمدتاً در محدوده منفی ۴۵ تا منفی ۶۰ درصد قرار دارد.این ترکیب شباهت قابل‌توجهی به وضعیت عمومی شرکت‌های فناوری در سه‌ماهه نخست ۲۰۲۲ دارد.به عبارت دیگر، در حالی که بخش بزرگی از بازار به سمت رشد کندتر و کاهش زیان حرکت کرده، شرکت‌هایی که اخیراً سرمایه جدید جذب کرده‌اند همچنان الگوی رشد سریع همراه با زیان‌دهی بالا را نشان می‌دهند.یکی از تفسیرهای ممکن این است که دسترسی به سرمایه تازه، به شرکت‌ها اجازه می‌دهد هزینه بیشتری برای توسعه، جذب مشتری و افزایش سهم بازار صرف کنند.با این حال، این داده‌ها به‌تنهایی ثابت نمی‌کنند که جذب سرمایه علت رشد سریع‌تر یا زیان‌دهی بیشتر است.ممکن است سرمایه‌گذاران اساساً شرکت‌هایی را برای تأمین مالی انتخاب کنند که از قبل رشد سریع‌تری داشته‌اند. همچنین، تفاوت در سن شرکت‌ها، مدل کسب‌وکار و مرحله توسعه می‌تواند بر این مقایسه اثر بگذارد.در نتیجه، وضعیت شرکت‌های تازه‌تأمین‌مالی‌شده را باید به‌عنوان یک الگوی متفاوت در داده‌ها در نظر گرفت، نه اثبات قطعی رابطه علّی میان جذب سرمایه و رشد.هرچند داده‌های SVB از تغییر محسوس الگوی رشد و سودآوری شرکت‌های فناوری حکایت دارند، برای نسبت دادن این تحول به هوش مصنوعی باید سه نکته را در نظر گرفت.نخست، سال ۲۰۲۲ نقطه شروعی استثنایی بود.دوره پیش از افزایش نرخ بهره، تحت تأثیر شرایط خاص اقتصادی قرار داشت؛ از جمله نرخ‌های بهره بسیار پایین، دسترسی گسترده به سرمایه و تغییر الگوهای مصرف و فعالیت اقتصادی در دوران همه‌گیری و بازگشایی پس از آن.در این شرایط، بسیاری از شرکت‌های فناوری رشد سریع و ارزش‌گذاری‌های بالایی را تجربه کردند.بنابراین، بخشی از کاهش رشد پس از سال ۲۰۲۲ می‌تواند ناشی از بازگشت بازار از یک دوره غیرعادی به شرایط متعارف‌تر باشد.در نتیجه، نباید تمام فاصله میان رشد ابتدای ۲۰۲۲ و رشد سال ۲۰۲۶ را صرفاً به ظهور هوش مصنوعی نسبت داد.دوم، چرخش از رشد به سودآوری پدیده‌ای محدود به استارتاپ‌ها نبود.افزایش نرخ بهره و تغییر شرایط تأمین مالی، تنها شرکت‌های خصوصی دارای پشتوانه سرمایه‌گذاری خطرپذیر را تحت تأثیر قرار نداد.شرکت‌های فناوری بورسی نیز با فشار بیشتری برای کنترل هزینه‌ها، بهبود حاشیه سود و افزایش بهره‌وری مواجه شدند.این موضوع نشان می‌دهد که بخشی از تغییر اولویت‌های عملیاتی، واکنشی گسترده به محیط اقتصاد کلان بوده است.هوش مصنوعی می‌تواند از طریق تغییر جهت سرمایه‌گذاری و تشدید رقابت، این تحول را تقویت کرده باشد، اما تنها عامل توضیح‌دهنده آن نیست.سوم، روند رشد در حال تغییر است و نشانه‌هایی از شتاب‌گیری دوباره دیده می‌شود.داده‌های اخیر نشان می‌دهند که رشد درآمد برخی بخش‌های فناوری ممکن است بار دیگر در حال افزایش باشد.بنابراین، کاهش رشد از سال ۲۰۲۲ را نباید یک روند دائمی یا برگشت‌ناپذیر تلقی کرد.ممکن است شرکت‌ها پس از یک دوره اصلاح ساختار هزینه و بهبود وضعیت مالی، دوباره سرمایه‌گذاری برای رشد را افزایش دهند.اگر چنین رشدی با حفظ حاشیه سود بهتر همراه باشد، می‌تواند نشان‌دهنده تغییر مهمی در الگوی عملیاتی شرکت‌های فناوری باشد؛ الگویی که در آن، رشد درآمد و بهبود سودآوری لزوماً در تعارض دائمی با یکدیگر قرار ندارند.با این حال، برای ارزیابی پایداری این روند به داده‌های بیشتر نیاز است.جمع‌بندی: از رشد به هر قیمت تا رشد همراه با انضباط مالیداده‌های SVB نشان می‌دهند که از ابتدای سال ۲۰۲۲ تا نیمه نخست ۲۰۲۶، الگوی عملیاتی شرکت‌های فناوری تغییر محسوسی کرده است.در ابتدای دوره، بسیاری از شرکت‌ها رشد درآمدی در محدوده ۴۰ تا ۷۰ درصد داشتند، اما این رشد با حاشیه سود عمیقاً منفی همراه بود.در پایان دوره، نرخ رشد عمدتاً به محدوده ۱۵ تا ۳۰ درصد کاهش یافته، اما حاشیه سود به‌طور قابل‌توجهی بهبود پیدا کرده است.این تغییر با افزایش نرخ بهره، دشوارتر شدن تأمین مالی و تغییر جهت سرمایه‌گذاری خطرپذیر به سمت هوش مصنوعی هم‌زمان بوده است.با این حال، شرکت‌هایی که اخیراً سرمایه جذب کرده‌اند، همچنان الگوی متفاوتی را نشان می‌دهند: رشد سریع همراه با زیان‌دهی بالا.این تفاوت بیانگر آن است که رویکرد رشد تهاجمی از بازار حذف نشده، بلکه شرایط تأمین مالی و ویژگی‌های شرکت‌ها می‌تواند بر امکان ادامه آن تأثیر بگذارد.نکته اصلی این است که در محیط جدید، رشد سریع دیگر به‌تنهایی معیار کافی برای ارزیابی عملکرد شرکت‌های فناوری نیست؛ توانایی تبدیل رشد درآمد به یک مدل کسب‌وکار پایدار و کاهش وابستگی به سرمایه خارجی نیز اهمیت بیشتری پیدا کرده است.در عین حال، شواهد موجود نشان نمی‌دهند که دوران رشد سریع به پایان رسیده است. بلکه بازار در حال تجربه تغییر در رابطه میان رشد، سودآوری و تأمین مالی است؛ تغییری که پیامدهای آن برای شرکت‌های قدیمی و نسل تازه استارتاپ‌های هوش مصنوعی ممکن است متفاوت باشد.</description><category>Amir Mokarchi</category><author>Amir Mokarchi</author><pubDate>Sat, 10 Oct 2026 20:42:52 +0330</pubDate></item><item><title>هوش مصنوعی چگونه مسیر رشد استارتاپ‌ها را تغییر می‌دهد؟</title><link>https://virgool.ir/@mokarchi/هوش-مصنوعی-چگونه-مسیر-رشد-استارتاپ-ها-را-تغییر-می-دهد-xl8vtk6fzg4o</link><description>آثار اولیه هوش مصنوعی بر اقتصاد، تنها در افزایش تعداد اپلیکیشن‌ها یا رشد استفاده از ابزارهای هوش مصنوعی دیده نمی‌شود. یکی دیگر از حوزه‌هایی که این تحول در آن نمود پیدا کرده، بازار سرمایه‌گذاری خطرپذیر (Venture Capital) و عملکرد شرکت‌هایی است که با حمایت سرمایه‌گذاران رشد می‌کنند.شواهد موجود نشان می‌دهند که هوش مصنوعی ممکن است در حال تغییر الگوی رشد استارتاپ‌ها باشد. از یک سو، بخش قابل‌توجهی از ارزش‌آفرینی در بازار سرمایه‌گذاری خطرپذیر در تعداد نسبتاً محدودی از شرکت‌ها متمرکز شده است. از سوی دیگر، داده‌های جدید از ظهور نسل متفاوتی از یونیکورن‌ها حکایت دارند؛ شرکت‌هایی که در سن پایین‌تری به ارزش‌گذاری میلیارددلاری می‌رسند و در برخی موارد، درآمدشان سریع‌تر از نسل‌های پیشین رشد می‌کند.داده‌های بانک سیلیکون‌ولی (Silicon Valley Bank یا SVB) دو تغییر مهم را در این زمینه نشان می‌دهند: کاهش سن یونیکورن‌های جدید و افزایش سرعت رشد درآمد در میان شرکت‌های تأسیس‌شده پس از گسترش هوش مصنوعی مولد.۱. یونیکورن‌های جدید در سن پایین‌تری متولد می‌شونددر گذشته، رسیدن به این سطح از ارزش‌گذاری معمولاً مستلزم چندین سال توسعه محصول، جذب سرمایه، گسترش بازار و افزایش درآمد بود. اما داده‌های SVB نشان می‌دهند که شرکت‌های جدید در مقایسه با نسل‌های پیشین، در سن پایین‌تری به این نقطه می‌رسند.نمودار نخست، میانه سن یونیکورن‌ها را طی سال‌های ۲۰۱۹ تا ۲۰۲۶ از دو منظر بررسی می‌کند: تمام یونیکورن‌های فعال و شرکت‌هایی که به‌تازگی به این جایگاه رسیده‌اند.افزایش سن مجموعه یونیکورن‌های فعالخط سبز نمودار، میانه سن تمام یونیکورن‌های فعال را نشان می‌دهد.این شاخص در سال ۲۰۱۹ حدود ۱۲ سال بود و با وجود افتی کوتاه در سال ۲۰۲۱، روندی عمدتاً صعودی داشته است. تا سال ۲۰۲۶، میانه سن این شرکت‌ها به حدود ۱۵ سال رسیده است.به بیان دیگر، مجموعه یونیکورن‌های موجود در بازار به‌تدریج در حال مسن‌تر شدن است.نمودار همچنین نشان می‌دهد که سن این مجموعه از سال ۲۰۲۳ تاکنون حدود ۷ درصد افزایش یافته است.این دو عدد باید از یکدیگر تفکیک شوند: افزایش سن از حدود ۱۲ به ۱۵ سال مربوط به کل دوره ۲۰۱۹ تا ۲۰۲۶ است، در حالی که رشد ۷ درصدی به بازه کوتاه‌ترِ آغازشده از سال ۲۰۲۳ اشاره دارد.کاهش سن یونیکورن‌های تازه‌واردخط آبی نمودار، میانه سن شرکت‌هایی را نشان می‌دهد که در هر دوره به‌تازگی به ارزش‌گذاری یک میلیارد دلاری رسیده‌اند.برخلاف مجموعه یونیکورن‌های فعال، این شاخص روندی نزولی داشته است.در سال ۲۰۱۹، میانه سن یونیکورن‌های جدید حدود ۷٫۲ سال بود. این رقم در سال ۲۰۲۶ به اندکی بیش از ۴ سال رسیده است.کاهش سن یونیکورن‌های جدید به‌ویژه از سال ۲۰۲۳ به بعد آشکارتر شده است؛ به‌طوری‌که طبق برچسب نمودار، میانه سن این شرکت‌ها در مقایسه با آن سال حدود ۳۷ درصد کاهش یافته است.در نتیجه، دو روند متضاد در بازار شکل گرفته‌اند: مجموعه یونیکورن‌های موجود در حال مسن‌تر شدن است، اما شرکت‌هایی که به‌تازگی وارد این گروه می‌شوند، به‌طور متوسط جوان‌تر از گذشته‌اند.این واگرایی نشان می‌دهد که نسل جدید استارتاپ‌ها ممکن است در مدت کوتاه‌تری به ارزش‌گذاری‌های میلیارددلاری دست پیدا کند.البته ارزش‌گذاری یک میلیارد دلاری لزوماً به معنای سودآوری، درآمد بالا یا پایداری مدل کسب‌وکار نیست. این ارزش‌گذاری می‌تواند تحت تأثیر انتظارات سرمایه‌گذاران درباره رشد آینده، شرایط بازار و میزان رقابت برای سرمایه‌گذاری نیز قرار گیرد.بنابراین، کاهش سن یونیکورن‌های جدید به‌تنهایی ثابت نمی‌کند که این شرکت‌ها از نظر عملکرد اقتصادی موفق‌تر از نسل‌های پیشین هستند.۲. نسل پس از GPT: آیا درآمد استارتاپ‌ها نیز سریع‌تر رشد می‌کند؟کاهش سن یونیکورن‌ها تنها یکی از نشانه‌های تغییر در بازار سرمایه‌گذاری خطرپذیر است.داده‌های SVB نشان می‌دهند که سرعت رشد درآمد شرکت‌های تأسیس‌شده در دوره گسترش هوش مصنوعی مولد نیز ممکن است با الگوی نسل‌های پیشین تفاوت داشته باشد.نمودار دوم، درآمد شرکت‌های دارای پشتوانه سرمایه‌گذاری خطرپذیر (VC-Backed Companies) را بر اساس تعداد سال‌های سپری‌شده از زمان تأسیس مقایسه می‌کند.در این بررسی، شرکت‌ها به هفت گروه یا کوهورت (Cohort) تقسیم شده‌اند که هرکدام شامل شرکت‌های تأسیس‌شده در یکی از سال‌های ۲۰۱۸ تا ۲۰۲۴ هستند.هدف این است که مشخص شود شرکت‌های نسل‌های مختلف، در سن یکسان، چه میزان درآمد داشته‌اند و با چه سرعتی رشد کرده‌اند.برای جلوگیری از آنکه عملکرد چند شرکت بسیار بزرگ تصویر کلی را تحت تأثیر قرار دهد، بزرگ‌ترین شرکت‌های هوش مصنوعی در مقیاس هایپراسکیل (AI Hyperscalers) از این مقایسه کنار گذاشته شده‌اند.در این نمودار، ستون‌های آبی روشن محدوده‌ای را نشان می‌دهند که ۵۰ درصد میانی شرکت‌های هر گروه در آن قرار گرفته‌اند.خط تیره، میانه درآمد شرکت‌ها را در هر سال از عمرشان نمایش می‌دهد و نقطه قرمز، میانه درآمد در پایان سال چهارم فعالیت را مشخص می‌کند.استفاده از میانه به‌جای میانگین اهمیت دارد؛ زیرا درآمد چند شرکت بسیار بزرگ می‌تواند میانگین را به‌شدت افزایش دهد و تصویر گمراه‌کننده‌ای از عملکرد شرکت‌های معمولی ارائه کند.در مقابل، میانه نشان می‌دهد که نیمی از شرکت‌های تحت پوشش درآمدی کمتر و نیمی دیگر درآمدی بیشتر از مقدار موردنظر داشته‌اند.الگوی رشد شرکت‌های تأسیس‌شده بین سال‌های ۲۰۱۸ تا ۲۰۲۱در کوهورت‌های ۲۰۱۸ تا ۲۰۲۱، رشد میانه درآمد نسبتاً تدریجی بوده است.درآمد میانه این شرکت‌ها در پایان سال چهارم فعالیت، عمدتاً در محدوده ۲ تا ۳ میلیون دلار قرار داشته است.به بیان ساده، الگوی معمول در این نسل‌ها چنین بوده که شرکتی با درآمد میانه حدود ۲ میلیون دلار در سال سوم، در سال چهارم به درآمدی نزدیک به ۳ میلیون دلار رسیده است.این روند نشان‌دهنده رشد سالانه است، اما جهشی ناگهانی در مسیر درآمد شرکت‌ها مشاهده نمی‌شود.کوهورت ۲۰۲۲: جهش محسوس در سال چهارمشرکت‌های تأسیس‌شده در سال ۲۰۲۲ الگوی متفاوتی را نشان می‌دهند.میانه درآمد این گروه در سال سوم فعالیت حدود ۲٫۸ میلیون دلار بوده، اما در سال چهارم به حدود ۵٫۶ میلیون دلار رسیده است.به این ترتیب، درآمد میانه این شرکت‌ها تنها طی یک سال تقریباً دو برابر شده است.به عبارت دیگر، تفاوت اصلی صرفاً این نیست که شرکت‌های نسل جدید در سال چهارم درآمد بیشتری دارند؛ بلکه سرعت افزایش درآمد آن‌ها نیز در این مقطع از چرخه عمرشان بالاتر بوده است.این یافته می‌تواند نشانه‌ای از تغییر در اقتصاد رشد استارتاپ‌ها باشد؛ تغییری که احتمالاً با گسترش هوش مصنوعی مولد ارتباط دارد.با این حال، برای اثبات چنین ارتباطی باید عوامل دیگری مانند ترکیب صنایع، شرایط سرمایه‌گذاری، مدل‌های درآمدی و تفاوت‌های ساختاری شرکت‌ها نیز بررسی شوند.۳. آیا می‌توان این تغییرات را مستقیماً به هوش مصنوعی نسبت داد؟داده‌های SVB شواهد قابل‌توجهی از تغییر الگوی رشد استارتاپ‌ها ارائه می‌کنند، اما نسبت دادن تمام این تغییرات به هوش مصنوعی نیازمند احتیاط است.برای تفسیر دقیق‌تر نتایج، چهار ملاحظه اساسی وجود دارد.نخست، هنوز برای ارزیابی پایداری روند زود است.کوهورت ۲۰۲۲ در پایان سال چهارم فعالیت، جهش قابل‌توجهی در درآمد میانه داشته است. با این حال، داده‌های شرکت‌های تأسیس‌شده در سال‌های ۲۰۲۳ و ۲۰۲۴ هنوز به‌ترتیب تنها سه و دو سال از عمر آن‌ها را پوشش می‌دهند.بنابراین، نمی‌توان با اطمینان گفت که این نسل‌ها نیز در سال چهارم رشد مشابهی را تجربه خواهند کرد.اگر کوهورت‌های بعدی همین الگو را تکرار کنند، شواهد بیشتری برای تغییر ساختاری در سرعت رشد استارتاپ‌ها فراهم خواهد شد. در مقابل، اگر جهش کوهورت ۲۰۲۲ تکرار نشود، ممکن است با پدیده‌ای مختص همان نسل مواجه باشیم.دوم، ترکیب شرکت‌های سرمایه‌گذاری‌شده در حال تغییر است.هوش مصنوعی تنها به افزایش تعداد شرکت‌های نرم‌افزاری منجر نشده است. بخشی از سرمایه‌گذاری‌های جدید به کسب‌وکارهای غیرنرم‌افزاری، از جمله زیرساخت، سخت‌افزار و سایر حوزه‌های مرتبط با هوش مصنوعی اختصاص یافته است.این شرکت‌ها ممکن است از نظر سرمایه موردنیاز، زمان عرضه محصول، حاشیه سود و سرعت رشد درآمد، الگوهای متفاوتی با شرکت‌های نرم‌افزاری داشته باشند.در نتیجه، تغییر ترکیب صنایع می‌تواند بر میانه درآمد و سایر شاخص‌های کل بازار اثر بگذارد.برای ارزیابی دقیق‌تر نقش هوش مصنوعی، لازم است عملکرد شرکت‌های مشابه در صنایع و مدل‌های کسب‌وکار یکسان نیز با یکدیگر مقایسه شود.سوم، احتمال تمرکز رشد در شرکت‌های موسوم به AI Wrappers وجود دارد.یکی از فرضیه‌های جایگزین این است که کوهورت ۲۰۲۲ شامل تعداد قابل‌توجهی از شرکت‌هایی باشد که محصول خود را بر پایه مدل‌ها و زیرساخت‌های هوش مصنوعی موجود ساخته‌اند.این محصولات که گاهی با عنوان «لایه‌های کاربردی مبتنی بر هوش مصنوعی» یا AI Wrappers شناخته می‌شوند، می‌توانند با تکیه بر مدل‌های آماده، بدون نیاز به توسعه زیرساخت بنیادی هوش مصنوعی، سریع‌تر وارد بازار شوند.چنین مدلی ممکن است به کاهش زمان توسعه، تسریع عرضه محصول و رشد سریع‌تر درآمد منجر شود.اما پرسش مهم این است که آیا این شرکت‌ها می‌توانند رشد اولیه خود را در بلندمدت حفظ کنند؟پایداری درآمد آن‌ها ممکن است به عواملی مانند وفاداری مشتریان، تمایز محصول، هزینه استفاده از مدل‌های زیربنایی، رقابت و توانایی حفظ مزیت رقابتی وابسته باشد.بنابراین، رشد سریع اولیه لزوماً به معنای شکل‌گیری یک کسب‌وکار پایدار نیست.چهارم، بزرگ‌ترین شرکت‌های هوش مصنوعی از تحلیل درآمد کنار گذاشته شده‌اند.یکی از ویژگی‌های مهم نمودار دوم این است که بزرگ‌ترین شرکت‌های هوش مصنوعی را از مجموعه داده حذف کرده است.در نتیجه، رشد مشاهده‌شده در میانه درآمد را نمی‌توان صرفاً به عملکرد استثنایی چند بازیگر بسیار بزرگ نسبت داد.این موضوع اهمیت یافته را افزایش می‌دهد، زیرا نشان می‌دهد تغییر الگوی درآمد در میان مجموعه گسترده‌تری از شرکت‌های تحت پوشش داده‌ها نیز مشاهده شده است.با این حال، حذف شرکت‌های بزرگ به‌تنهایی اثر هوش مصنوعی را اثبات نمی‌کند و سایر عوامل مؤثر همچنان باید بررسی شوند.</description><category>Amir Mokarchi</category><author>Amir Mokarchi</author><pubDate>Sat, 10 Oct 2026 20:40:37 +0330</pubDate></item><item><title>هوش مصنوعی میلیاردها کاربر بالقوه دارد؛ اما چند نفر مشتری واقعی‌اند؟</title><link>https://virgool.ir/@mokarchi/هوش-مصنوعی-میلیاردها-کاربر-بالقوه-دارد-اما-چند-نفر-مشتری-واقعی-اند-bsyfelkoyoc4</link><description>با وجود رشد چشمگیر اپلیکیشن‌های هوش مصنوعی و افزایش استقبال از محصولاتی مانند ChatGPT، Claude و Gemini، بررسی رفتار پرداخت مصرف‌کنندگان تصویر متفاوتی از میزان نفوذ اقتصادی این فناوری ارائه می‌دهد.داده‌های تراکنشی شرکت Consumer Edge نشان می‌دهند که اگرچه تعداد افرادی که شخصاً برای خدمات هوش مصنوعی هزینه می‌کنند رو‌به‌افزایش است، پذیرش پولی این خدمات در میان مصرف‌کنندگان آمریکایی همچنان در سطح نسبتاً پایینی قرار دارد.بر اساس این داده‌ها، در سه‌ماهه نخست سال ۲۰۲۶، حدود ۳ درصد از مصرف‌کنندگان آمریکاییِ تحت پوشش داده‌های پژوهش، با استفاده از کارت‌های اعتباری یا نقدی شخصی خود برای خدمات هوش مصنوعی پرداخت کرده‌اند.این رقم در نگاه نخست ممکن است کوچک به نظر برسد، اما بررسی روند تاریخی و تفاوت میان گروه‌های سنی نشان می‌دهد که بازار در حال تغییر است و نسل‌های جوان‌تر نقش برجسته‌تری در گسترش پذیرش پولی هوش مصنوعی دارند.نمودار Consumer Edge، سهم مصرف‌کنندگانی را که برای خدمات هوش مصنوعی پرداخت کرده‌اند، در شش گروه سنی و طی بازه سه‌ماهه نخست ۲۰۲۳ تا سه‌ماهه نخست ۲۰۲۶ مقایسه می‌کند.این نمودار نشان می‌دهد که رشد پذیرش پولی در تمام گروه‌های سنی اتفاق افتاده است، اما سرعت و میزان آن یکسان نیست.تا اواخر سال ۲۰۲۴، سهم خریداران خدمات هوش مصنوعی در تمام گروه‌های سنی کمتر از ۲ درصد بود و منحنی‌های نمودار فاصله چندانی از یکدیگر نداشتند.از ابتدای سال ۲۰۲۵، روند متفاوتی شکل گرفت. سهم خریداران در گروه‌های جوان‌تر با سرعت بیشتری افزایش یافت و فاصله میان گروه‌های سنی به‌تدریج بیشتر شد.۱. گروه سنی ۱۸ تا ۲۴ سال: پیشتاز در پذیرش پولیمصرف‌کنندگان ۱۸ تا ۲۴ ساله بالاترین نرخ پذیرش پولی هوش مصنوعی را در میان گروه‌های بررسی‌شده دارند.سهم خریداران در این گروه از حدود ۰٫۷ درصد در ابتدای سال ۲۰۲۳ به نزدیک ۵٫۹ درصد در سه‌ماهه نخست ۲۰۲۶ رسیده است.رشد این گروه به‌ویژه از ابتدای سال ۲۰۲۵ شتاب گرفته و منحنی آن از سایر گروه‌های سنی فاصله گرفته است.این داده‌ها نشان می‌دهند که جوان‌ترین گروه مصرف‌کنندگان بزرگسال، آمادگی بیشتری برای پرداخت مستقیم هزینه خدمات هوش مصنوعی از خود نشان داده‌اند.با این حال، حتی در این گروه نیز کمتر از ۶ درصد مصرف‌کنندگان تحت پوشش داده‌ها، پرداخت شخصی برای خدمات هوش مصنوعی داشته‌اند. بنابراین، با وجود رشد سریع، پذیرش پولی هنوز به رفتاری فراگیر تبدیل نشده است.۲. گروه‌های سنی ۲۵ تا ۴۴ سال: رشد قابل‌توجه و فاصله اندکدر میان مصرف‌کنندگان ۲۵ تا ۳۴ ساله، سهم خریداران خدمات هوش مصنوعی تا سه‌ماهه نخست ۲۰۲۶ به حدود ۵ درصد رسیده است.گروه سنی ۳۵ تا ۴۴ سال نیز با نرخ پذیرش نزدیک به ۴٫۷ درصد، فاصله چندانی با گروه قبلی ندارد.رشد این دو گروه نشان می‌دهد که پرداخت برای خدمات هوش مصنوعی صرفاً به جوان‌ترین کاربران محدود نیست و در میان بزرگسالان نیز در حال گسترش است.با این حال، داده‌های نمودار به‌تنهایی مشخص نمی‌کنند که این پرداخت‌ها با چه انگیزه‌ای انجام شده‌اند. استفاده شخصی، فعالیت حرفه‌ای، آموزش یا نیازهای مرتبط با کسب‌وکار می‌توانند از جمله کاربردهای احتمالی باشند، اما تعیین سهم هرکدام به اطلاعات تکمیلی نیاز دارد.۳. گروه‌های سنی ۴۵ تا ۶۴ سال: رشد ملایم‌تردر گروه سنی ۴۵ تا ۵۴ سال، سهم مصرف‌کنندگانی که شخصاً برای خدمات هوش مصنوعی هزینه کرده‌اند، به حدود ۳٫۸ درصد رسیده است.این رقم برای گروه سنی ۵۵ تا ۶۴ سال حدود ۲٫۶ درصد است.هر دو گروه نسبت به سال‌های ابتدایی دوره بررسی‌شده رشد داشته‌اند، اما سرعت افزایش پذیرش در آن‌ها کمتر از گروه‌های جوان‌تر بوده است.این تفاوت نشان می‌دهد که گسترش پرداخت مستقیم برای خدمات هوش مصنوعی در میان گروه‌های سنی مختلف با سرعت یکسانی اتفاق نمی‌افتد.البته پایین‌تر بودن نرخ پرداخت شخصی الزاماً به معنای استفاده کمتر از هوش مصنوعی نیست. برخی کاربران ممکن است از خدمات رایگان استفاده کنند یا هزینه دسترسی آن‌ها توسط کارفرما و سازمان پرداخت شود؛ مواردی که در این داده‌ها منعکس نمی‌شوند.۴. گروه سنی ۶۵ سال و بالاتر: پایین‌ترین نرخ پذیرش پولیدر میان مصرف‌کنندگان ۶۵ ساله و بالاتر، سهم خریداران خدمات هوش مصنوعی در سه‌ماهه نخست ۲۰۲۶ به حدود ۱٫۴ درصد رسیده است.این گروه پایین‌ترین نرخ پذیرش پولی را در نمودار دارد.مقایسه آن با گروه ۱۸ تا ۲۴ سال نشان می‌دهد که نرخ پرداخت شخصی در میان جوان‌ترین گروه بزرگسال، تقریباً ۴٫۲ برابر گروه ۶۵ سال و بالاتر است.این شکاف می‌تواند تحت تأثیر تفاوت در نیازها، الگوهای استفاده از فناوری، آشنایی با ابزارهای دیجیتال و تمایل به پرداخت باشد. با این حال، داده‌های موجود به‌تنهایی امکان تعیین سهم هر یک از این عوامل را فراهم نمی‌کنند.مقایسه گروه‌های سنی دو نکته مهم را آشکار می‌کند: نخست اینکه پرداخت مستقیم برای خدمات هوش مصنوعی در تمام گروه‌های سنی رو‌به‌افزایش است؛ دوم اینکه نرخ پذیرش با افزایش سن، به‌طور کلی کاهش می‌یابد.با این حال، حتی بالاترین نرخ ثبت‌شده نیز کمتر از ۶ درصد است. این موضوع نشان می‌دهد که پرداخت شخصی برای خدمات هوش مصنوعی، با وجود رشد سریع، هنوز در میان اکثریت مصرف‌کنندگان فراگیر نشده است.محدودیت روش‌شناختی: عدد ۳ درصد دقیقاً چه چیزی را اندازه می‌گیرد؟در تفسیر این داده‌ها باید به یک محدودیت اساسی توجه کرد.آمار Consumer Edge بر تراکنش‌های ثبت‌شده با کارت‌های اعتباری و نقدی مصرف‌کنندگان استوار است. بنابراین، این داده‌ها صرفاً بخشی از بازار خدمات هوش مصنوعی را نشان می‌دهند که پرداخت آن مستقیماً توسط افراد و از طریق کارت‌های تحت پوشش انجام شده است.در نتیجه، چند بخش مهم از مصرف و درآمد هوش مصنوعی در این شاخص منعکس نمی‌شوند.پرداخت‌های سازمانی و کارفرمایی: بسیاری از کاربران از طریق اشتراک‌های سازمانی یا حساب‌هایی که هزینه آن‌ها توسط کارفرما پرداخت می‌شود، به خدمات هوش مصنوعی دسترسی دارند. این نوع پرداخت‌ها در شاخص خرید شخصی مصرف‌کنندگان دیده نمی‌شوند.استفاده از نسخه‌های رایگان: بخش قابل‌توجهی از کاربران ممکن است از خدمات هوش مصنوعی استفاده کنند، اما هیچ هزینه مستقیمی برای آن نپردازند. این افراد نیز در آمار پذیرش پولی حضور ندارند.تراکنش‌های خارج از پوشش داده‌ها: پرداخت‌هایی که از طریق ابزارهای پرداخت، حساب‌ها یا مسیرهای خارج از مجموعه داده Consumer Edge انجام می‌شوند، ممکن است در این برآورد ثبت نشده باشند.بنابراین، رقم ۳ درصد را نباید معادل سهم کل کاربران هوش مصنوعی در جامعه آمریکا یا میزان نفوذ اقتصادی این فناوری در نظر گرفت.این عدد، شاخصی از پرداخت مستقیم مصرف‌کنندگان در محدوده تراکنش‌های تحت پوشش پژوهش است.همچنین، از نظر روش‌شناختی دقیق نیست که این رقم را بدون بررسی پوشش و نمایندگی داده‌ها، کف قطعی پذیرش پولی در کل جمعیت آمریکا بدانیم. با این حال، روشن است که این شاخص تمام مسیرهای استفاده و پرداخت برای خدمات هوش مصنوعی را در بر نمی‌گیرد.</description><category>Amir Mokarchi</category><author>Amir Mokarchi</author><pubDate>Sat, 10 Oct 2026 20:38:07 +0330</pubDate></item><item><title>چه زمانی اثر هوش مصنوعی در تولید ناخالص داخلی نمایان می‌شود؟</title><link>https://virgool.ir/@mokarchi/چه-زمانی-اثر-هوش-مصنوعی-در-تولید-ناخالص-داخلی-نمایان-می-شود-tnf9r7vunp1v</link><description>نمودار حبابی سنسورتاور، عملکرد دسته‌های مختلف اپلیکیشن را در بازار ایالات متحده از سه منظر مقایسه می‌کند: رشد درآمد، رشد زمان استفاده و اندازه اقتصادی هر دسته.محور افقی، درصد تغییر مجموع زمان صرف‌شده کاربران در اپلیکیشن‌ها (Time-Spent Growth) را نشان می‌دهد و از حدود منفی ۴۵ درصد تا مثبت ۶۰ درصد امتداد دارد.محور عمودی، درصد رشد درآمد (Revenue Growth) را نمایش می‌دهد و محدوده‌ای از منفی ۵۰ درصد تا مثبت ۱۵۰ درصد را پوشش می‌دهد.اندازه هر حباب نیز متناسب با درآمد آن دسته است. برای درک مقیاس، نمودار از حباب‌های مرجع با درآمد ۱۰۰ میلیون، ۵۰۰ میلیون و یک میلیارد دلار استفاده می‌کند.این شیوه نمایش کمک می‌کند سه موضوع را هم‌زمان بررسی کنیم: کدام دسته‌ها کاربران را بیشتر درگیر کرده‌اند، کدام دسته‌ها درآمد بیشتری ایجاد می‌کنند و رشد مشاهده‌شده در چه مقیاسی از بازار اتفاق افتاده است.۱. بهره‌وری (Productivity): رشد هم‌زمان درآمد و استفادهدسته بهره‌وری برجسته‌ترین بخش نمودار است.این دسته در ناحیه بالا و راست قرار گرفته و تنها حباب تیره و متمایز نمودار را تشکیل می‌دهد. چنین موقعیتی نشان می‌دهد که بهره‌وری هم از نظر درآمد و هم از نظر زمان استفاده، رشد قابل‌توجهی داشته است.درآمد این دسته بیش از ۱۰۰ درصد افزایش یافته و رشد زمان استفاده کاربران نیز به حدود ۶۰ درصد رسیده است.بر اساس داده‌های ارائه‌شده، بهره‌وری سریع‌ترین رشد زمان استفاده را در میان دسته‌های بررسی‌شده داشته و از نظر رشد درآمد نیز پس از دسته نسبتاً کوچک غذا و نوشیدنی در جایگاه دوم قرار گرفته است.نکته مهم این است که این رشد صرفاً به یک بازار کوچک و نوظهور محدود نمی‌شود. اندازه حباب بهره‌وری نشان می‌دهد که با دسته‌ای دارای مقیاس اقتصادی قابل‌توجه روبه‌رو هستیم.از محصولات شاخص این دسته می‌توان به ChatGPT، Claude، Gemini و Grok اشاره کرد.این محصولات، برخلاف بسیاری از اپلیکیشن‌هایی که صرفاً با کمک هوش مصنوعی ساخته می‌شوند، خودِ قابلیت‌های هوش مصنوعی را به‌عنوان بخش اصلی ارزش پیشنهادی محصول در اختیار کاربران قرار می‌دهند.رشد دسته بهره‌وری نشان می‌دهد که تقاضا برای استفاده مستقیم از قابلیت‌های هوش مصنوعی، دست‌کم در این بخش از بازار، به افزایش قابل‌توجه تعامل کاربران و درآمد منجر شده است.۲. غذا و نوشیدنی (Food &amp; Drink): رشد درآمد بالا در بازاری کوچکدسته غذا و نوشیدنی با رشد درآمدی در حدود ۱۲۵ درصد، بالاترین نرخ رشد درآمد را در میان دسته‌های بررسی‌شده ثبت کرده است.با این حال، اندازه حباب این دسته بسیار کوچک است و رشد زمان استفاده کاربران نیز چندان قابل‌توجه نیست.این تفاوت نشان می‌دهد که درصد رشد به‌تنهایی برای سنجش اهمیت اقتصادی یک دسته کافی نیست.برای مثال، افزایش درآمد یک بازار کوچک از ۱۰ میلیون دلار به ۲۰ میلیون دلار، رشدی ۱۰۰ درصدی محسوب می‌شود؛ اما از نظر ارزش مطلق، با رشد ۲۰ درصدی بازاری که چند میلیارد دلار درآمد دارد، قابل‌مقایسه نیست.بنابراین، اگرچه غذا و نوشیدنی بالاترین نرخ رشد درآمد را ثبت کرده، رشد آن از نظر مقیاس اقتصادی با رشد دسته بهره‌وری یکسان نیست.همچنین، افزایش درآمد بدون رشد متناسب زمان استفاده می‌تواند ناشی از عوامل مختلفی مانند افزایش پرداخت به‌ازای هر کاربر، تغییر قیمت‌ها یا تغییر ترکیب خدمات باشد. داده‌های نمودار به‌تنهایی برای تعیین علت این اختلاف کافی نیستند.۳. ابزارهای توسعه‌دهندگان (Developer Tools): رشد قابل‌توجه در مقیاسی محدوددسته ابزارهای توسعه‌دهندگان نیز در ناحیه بالا و راست نمودار قرار دارد؛ یعنی هم درآمد و هم زمان استفاده کاربران در این دسته افزایش یافته است.با این حال، اندازه حباب آن بسیار کوچک است و نشان می‌دهد که این بازار، در مقایسه با دسته‌های بزرگ‌تر، هنوز مقیاس اقتصادی محدودی دارد.بر اساس گزارش، Replit یکی از محصولات شاخص این دسته است و نقش برجسته‌ای در رشد آن داشته است.اهمیت این دسته در آن است که استفاده از هوش مصنوعی را به فرایند تولید نرم‌افزار پیوند می‌دهد.ابزارهایی مانند Replit می‌توانند بخشی از فعالیت‌های برنامه‌نویسی، ساخت نمونه اولیه و توسعه محصول را ساده‌تر کنند. در نتیجه، رشد این دسته را می‌توان نشانه‌ای از افزایش استقبال از ابزارهایی دانست که خودِ فرایند ساخت نرم‌افزار را تغییر می‌دهند.البته کوچک بودن اندازه بازار نشان می‌دهد که رشد سریع این ابزارها هنوز الزاماً به معنای سهم بزرگ آن‌ها از درآمد کل اقتصاد اپلیکیشن‌ها نیست.۴. سایر دسته‌ها: رشد نامتوازن و الگوهای متفاوت مصرفبخش میانی نمودار مجموعه‌ای از دسته‌ها را نشان می‌دهد که رشد درآمد یا زمان استفاده آن‌ها مثبت است، اما عملکردشان به‌اندازه دسته بهره‌وری برجسته نیست.دسته‌های مرجع (Reference)، مسیریابی (Navigation) و ابزارهای کاربردی (Utilities) به‌ترتیب رشد درآمدی در حدود ۴۶، ۴۴ و ۴۰ درصد ثبت کرده‌اند.موسیقی (Music) نیز حدود ۲۶ درصد رشد درآمد داشته است. شبکه‌های اجتماعی (Social Networking) با وجود رشد درآمدی نزدیک به ۲۵ درصد، کاهش قابل‌توجهی در مجموع زمان استفاده کاربران تجربه کرده‌اند.این اختلاف نشان می‌دهد که افزایش درآمد لزوماً با افزایش زمان استفاده همراه نیست.در دسته گرافیک و طراحی (Graphics &amp; Design)، وضعیت تقریباً معکوس است. زمان استفاده کاربران بیش از ۵۰ درصد افزایش یافته، اما رشد درآمد نزدیک به صفر باقی مانده است.چنین الگویی نشان می‌دهد که افزایش تعامل کاربران، دست‌کم در دوره بررسی‌شده، به رشد متناسب درآمد تبدیل نشده است.دسته‌های دیگری مانند آب‌وهوا، پزشکی، کسب‌وکار، سفر، عکس و ویدئو، سلامت و تناسب‌اندام، آموزش، امور مالی، خرید و اخبار نیز در بخش میانی نمودار قرار گرفته‌اند و الگوهای متفاوتی از رشد درآمد و زمان استفاده را نشان می‌دهند.مجموع این داده‌ها یادآور می‌شود که نمی‌توان وضعیت بازار اپلیکیشن‌ها را صرفاً با یک شاخص یا یک روند کلی توصیف کرد. هر دسته ممکن است تحت تأثیر عوامل متفاوتی رشد کند و رابطه میان درآمد و میزان استفاده نیز در تمام بخش‌ها یکسان نیست.۵. بازی‌ها، سبک زندگی و کتاب‌ها: کاهش درآمد در برخی بخش‌هادر مقابل دسته‌های رو‌به‌رشد، برخی بخش‌های بازار با کاهش درآمد مواجه شده‌اند.بازی‌ها (Games) بزرگ‌ترین حباب نمودار را تشکیل می‌دهند؛ موضوعی که نشان‌دهنده سهم اقتصادی قابل‌توجه این دسته در بازار اپلیکیشن‌هاست.با این حال، درآمد بازی‌ها حدود ۱۵ درصد کاهش یافته و رشد زمان استفاده نیز منفی بوده است.دسته سبک زندگی (Lifestyle) افت درآمدی نزدیک به ۳۰ درصد را تجربه کرده، در حالی که زمان استفاده کاربران در آن حدود ۱۲ درصد افزایش یافته است.این اختلاف نشان می‌دهد که کاربران ممکن است زمان بیشتری را صرف یک دسته از اپلیکیشن‌ها کنند، اما این افزایش تعامل لزوماً به درآمد بیشتر منجر نشود.دسته کتاب‌ها (Books) نیز با کاهش درآمدی نزدیک به ۴۰ درصد، یکی از شدیدترین افت‌های درآمدی را ثبت کرده است. در همین دوره، مجموع زمان استفاده از اپلیکیشن‌های این دسته تقریباً بدون تغییر باقی مانده است.این الگوها نشان می‌دهند که رشد تعداد کاربران، افزایش زمان استفاده و افزایش درآمد، سه پدیده متفاوت‌اند و نباید آن‌ها را معادل یکدیگر در نظر گرفت.بررسی رشد درآمد و زمان استفاده در دسته‌های مختلفبررسی شاخص‌های کلان بازار اپلیکیشن‌ها در ایالات متحده نشان می‌دهد که با وجود افزایش چشمگیر تعداد محصولات جدید، درآمد کل و مجموع زمان استفاده کاربران رشد چندانی نداشته‌اند. اما این تصویر کلی، تفاوت‌های مهم میان دسته‌های مختلف اپلیکیشن‌ها را پنهان می‌کند.وقتی داده‌ها را در سطح دسته‌بندی‌ها بررسی می‌کنیم، تصویر متفاوتی آشکار می‌شود: در حالی که بسیاری از بخش‌های بازار با رشد محدود یا حتی کاهش درآمد مواجه‌اند، دسته‌هایی که میزبان محصولات برجسته هوش مصنوعی هستند، رشد قابل‌توجهی را تجربه می‌کنند.داده‌های سنسورتاور (Sensor Tower) نشان می‌دهند که این تفاوت به‌ویژه در دسته بهره‌وری (Productivity) و تا حدودی در ابزارهای توسعه‌دهندگان (Developer Tools) مشهود است.با کنار هم قرار دادن نتایج این بررسی و داده‌های مربوط به افزایش عرضه اپلیکیشن‌ها، تمایز مهمی آشکار می‌شود.از یک سو، ابزارهای هوش مصنوعی تولید نرم‌افزار را آسان‌تر کرده‌اند و تعداد اپلیکیشن‌های جدید به‌شدت افزایش یافته است. با این حال، رشد عرضه با افزایش متناسب دانلودها، درآمد یا زمان استفاده همراه نبوده و سهم محصولاتی که به حداقلی از استقبال کاربران می‌رسند نیز کاهش یافته است.از سوی دیگر، محصولاتی که قابلیت‌های هوش مصنوعی را مستقیماً در اختیار کاربران قرار می‌دهند، به‌ویژه در دسته بهره‌وری، رشد چشمگیری را تجربه کرده‌اند.این دو روند، تفاوت میان دو مفهوم را برجسته می‌کنند:اپلیکیشن‌های مبتنی بر هوش مصنوعی (AI-Powered Apps): محصولاتی که هوش مصنوعی بخش اصلی ارزش پیشنهادی آن‌هاست و کاربران برای بهره‌مندی از قابلیت‌هایی مانند تولید محتوا، تحلیل اطلاعات، برنامه‌نویسی یا انجام وظایف پیچیده به سراغشان می‌روند.اپلیکیشن‌های ساخته‌شده با هوش مصنوعی (AI-Built Apps): محصولاتی که هوش مصنوعی در فرایند توسعه آن‌ها به کار گرفته شده است، اما لزوماً قابلیت هوش مصنوعی یا ارزش متمایزی را به کاربر نهایی ارائه نمی‌کنند.البته این دو گروه کاملاً مستقل از یکدیگر نیستند. یک محصول ممکن است هم با کمک هوش مصنوعی ساخته شده باشد و هم قابلیت‌های هوش مصنوعی را به کاربران ارائه دهد.با این حال، داده‌های موجود نشان می‌دهند که رشد تقاضا برای محصولات هوش مصنوعی را نباید با رشد تقاضا برای تمام نرم‌افزارهایی که به کمک هوش مصنوعی تولید می‌شوند، یکسان دانست.«اپلیکیشن‌هایی که هوش مصنوعی را به کاربران ارائه می‌کنند، با استقبال چشمگیری مواجه شده‌اند؛ اما اپلیکیشن‌هایی که صرفاً با کمک هوش مصنوعی ساخته می‌شوند، لزوماً چنین استقبالی را تجربه نکرده‌اند.»</description><category>Amir Mokarchi</category><author>Amir Mokarchi</author><pubDate>Sat, 10 Oct 2026 20:34:08 +0330</pubDate></item><item><title>شکاف میان عرضه و تقاضا در اقتصاد اپلیکیشن‌ها</title><link>https://virgool.ir/@mokarchi/شکاف-میان-عرضه-و-تقاضا-در-اقتصاد-اپلیکیشن-ها-ovjj4fdnzmcy</link><description>افزایش چشمگیر تعداد اپلیکیشن‌های جدید، این پرسش را مطرح می‌کند که آیا رشد عرضه توانسته است رونقی مشابه در اقتصاد اپلیکیشن‌ها ایجاد کند؟ به بیان دقیق‌تر، آیا کاربران پول بیشتری برای اپلیکیشن‌ها پرداخت می‌کنند و زمان بیشتری را به استفاده از آن‌ها اختصاص می‌دهند؟داده‌های شرکت سنسورتاور (Sensor Tower) نشان می‌دهند که دست‌کم در بازار ایالات متحده، پاسخ به این پرسش چندان مثبت نیست.بر اساس برآوردهای این شرکت، درآمد کل اپلیکیشن‌ها از دسامبر ۲۰۲۴ تا آگوست ۲۰۲۶ تقریباً ثابت مانده و تنها رشد محدودی را تجربه کرده است. در همین دوره، مجموع زمان صرف‌شده کاربران در اپلیکیشن‌ها نیز افزایش یافته، اما این رشد در مقایسه با جهش تعداد اپلیکیشن‌های جدید، نسبتاً ملایم بوده است.این یافته‌ها با نتایج پژوهش پیشین همخوانی دارند: افزایش قابل‌توجه ظرفیت تولید نرم‌افزار، لزوماً به افزایش متناسب تقاضا، درآمد یا میزان استفاده کاربران منجر نشده است.بررسی داده‌های درآمد و زمان استفادهنمودار سنسورتاور، روند تغییرات درآمد و مجموع زمان استفاده از اپلیکیشن‌ها در ایالات متحده را برای تمام دسته‌بندی‌ها، از جمله بازی‌ها (Games)، نشان می‌دهد.برای مقایسه این دو شاخص، مقدار هرکدام در دسامبر ۲۰۲۴ برابر با ۱۰۰ در نظر گرفته شده است. بنابراین، تغییرات بعدی نشان می‌دهند که هر شاخص نسبت به سطح اولیه خود چه میزان افزایش یا کاهش یافته است.۱. درآمد اپلیکیشن‌ها: رشد محدود و ناپایدارخط آبی پیوسته در نمودار، تغییرات درآمد کل اپلیکیشن‌ها (Revenue) را نشان می‌دهد.در طول دوره بررسی‌شده، شاخص درآمد عمدتاً در محدوده ۹۶ تا ۱۰۷ نوسان کرده و در آگوست ۲۰۲۶ به عدد ۱۰۲ رسیده است.این یعنی درآمد کل اپلیکیشن‌ها نسبت به دسامبر ۲۰۲۴ تنها حدود ۲ درصد افزایش یافته است.نکته مهم این است که این رشد محدود، با وجود افزایش چشمگیر تعداد اپلیکیشن‌های جدید رخ داده است. بنابراین، داده‌ها نشان نمی‌دهند که گسترش عرضه توانسته باشد جهشی متناسب در درآمد کل بازار ایجاد کند.البته باید میان درآمد کل بازار و درآمد تک‌تک اپلیکیشن‌ها تمایز قائل شد. ثابت ماندن درآمد کل به این معنا نیست که هیچ اپلیکیشنی رشد نکرده است؛ بلکه ممکن است برخی محصولات رشد قابل‌توجهی داشته باشند و در مقابل، درآمد سایر محصولات کاهش یافته باشد.۲. زمان استفاده کاربران: افزایش ملایم تقاضاخط طلاییِ خط‌چین، مجموع زمان صرف‌شده کاربران در اپلیکیشن‌ها (Total Time Spent) را نشان می‌دهد.این شاخص در آگوست ۲۰۲۶ به عدد ۱۰۷ رسیده است؛ به این معنا که مجموع زمان استفاده کاربران نسبت به دسامبر ۲۰۲۴ حدود ۷ درصد افزایش یافته است.در طول دوره بررسی‌شده، شاخص زمان استفاده در مقاطعی حتی به نزدیکی ۱۱۰ رسیده، اما نتوانسته است این سطح را به‌صورت پایدار حفظ کند.این افزایش نشان می‌دهد که میزان تعامل کاربران با اپلیکیشن‌ها تا حدودی رشد کرده است. با این حال، رشد ۷ درصدی زمان استفاده، در مقایسه با افزایش چندبرابری تعداد اپلیکیشن‌های جدید، محدود است.به عبارت دیگر، کاربران در مجموع اندکی بیشتر از گذشته از اپلیکیشن‌ها استفاده می‌کنند، اما این افزایش تقاضا با سرعت رشد عرضه همگام نبوده است.۳. نوسانات بازار: فقدان یک روند صعودی پایدارهر دو شاخص درآمد و زمان استفاده، طی دوره بررسی‌شده نوسانات قابل‌توجهی داشته‌اند.در اوایل سال ۲۰۲۵ و همچنین حوالی زمستان ۲۰۲۵ تا ۲۰۲۶، هر دو شاخص به زیر سطح پایه ۱۰۰ کاهش یافته‌اند.این نوسانات نشان می‌دهند که رشد مشاهده‌شده، روندی یکنواخت و مستمر نداشته است. در واقع، بازار دوره‌هایی از کاهش درآمد و افت زمان استفاده را نیز تجربه کرده و سپس بخشی از این کاهش‌ها جبران شده است.با این حال، صرف مشاهده این نوسانات برای تعیین علت آن‌ها کافی نیست. عواملی مانند تغییرات فصلی، شرایط اقتصادی، الگوی مصرف کاربران و تغییر ترکیب اپلیکیشن‌های پرمخاطب می‌توانند بر روند درآمد و زمان استفاده تأثیر بگذارند.برآوردهای سنسورتاور نشان می‌دهند که طی حدود ۲۰ ماه، درآمد کل اپلیکیشن‌ها در ایالات متحده تنها ۲ درصد و مجموع زمان استفاده کاربران حدود ۷ درصد افزایش یافته است.این ارقام در مقایسه با رشد چندبرابری تعداد اپلیکیشن‌های جدید، از شکاف قابل‌توجهی میان افزایش عرضه و رشد تقاضا حکایت دارند.البته داده‌های موجود به‌تنهایی نشان نمی‌دهند که افزایش عرضه هیچ تأثیری بر درآمد یا رفتار کاربران نداشته است. همچنین، بدون بررسی دقیق‌تر ترکیب درآمدها، تعداد کاربران فعال، نرخ نگهداشت و عملکرد دسته‌های مختلف اپلیکیشن‌ها، نمی‌توان درباره وضعیت اقتصادی تمام محصولات جدید حکم یکسانی صادر کرد.با این حال، تصویر کلی روشن است: کاهش موانع تولید نرم‌افزار، دست‌کم در دوره بررسی‌شده، با رونقی متناسب در درآمد و زمان استفاده همراه نشده است.جمع‌بندی اصلی این است که هوش مصنوعی ظرفیت تولید اپلیکیشن را به‌سرعت افزایش داده، اما رشد تقاضای کاربران و درآمد بازار با همان سرعت پیش نرفته است. در نتیجه، صرف افزایش تعداد محصولات جدید را نمی‌توان نشانه‌ای از رونق اقتصادی صنعت نرم‌افزار دانست.</description><category>Amir Mokarchi</category><author>Amir Mokarchi</author><pubDate>Mon, 28 Sep 2026 07:21:41 +0330</pubDate></item><item><title>رشد عرضه، رکود تقاضا؛ اقتصاد اپلیکیشن‌ها در عصر کدنویسی مبتنی بر هوش مصنوعی</title><link>https://virgool.ir/@mokarchi/رشد-عرضه-رکود-تقاضا-اقتصاد-اپلیکیشن-ها-در-عصر-کدنویسی-مبتنی-بر-هوش-مصنوعی-y6tpb7tevzqz</link><description>در حالی که عرضه اپلیکیشن‌های جدید به‌شدت افزایش یافته، نشانه‌های رشد تقاضا به همان نسبت افزایش پیدا نکرده‌اند. به بیان دیگر، ساخت و انتشار اپلیکیشن آسان‌تر شده است، اما این افزایش عرضه لزوماً به جذب کاربران بیشتر یا موفقیت تجاری محصولات جدید منجر نشده است.این پژوهش با بررسی داده‌های سه پلتفرم iOS، اندروید (Android) و کروم (Chrome)، سه روند اصلی را شناسایی می‌کند:نخست، تعداد اپلیکیشن‌های جدید منتشرشده در هر ماه، بسته به پلتفرم، حدود دو تا چهار برابر شده است. این افزایش نشان می‌دهد که ظرفیت تولید و انتشار نرم‌افزار به شکل چشمگیری رشد کرده است.دوم، شاخص‌های تقاضا رشد متناسبی را تجربه نکرده‌اند. تعداد دانلودهای اپلیکیشن‌های جدید در اندروید تقریباً ثابت مانده و در کروم کاهش یافته است. در iOS نیز تعداد امتیازهای ثبت‌شده برای اپلیکیشن‌های جدید، که در این پژوهش به‌عنوان شاخصی غیرمستقیم از میزان استقبال کاربران استفاده شده، روند صعودی مشخصی ندارد.سوم، حتی سهم اپلیکیشن‌هایی که موفق به جذب حداقلی از کاربران می‌شوند نیز کاهش یافته است. بنابراین، مسئله صرفاً این نیست که تعداد بیشتری اپلیکیشن برای جذب حجم ثابتی از تقاضا رقابت می‌کنند؛ بلکه نسبت محصولاتی که از مرحله انتشار اولیه عبور می‌کنند و به سطح مشخصی از استقبال کاربران می‌رسند نیز کمتر شده است.پژوهشگران برای سنجش این موضوع، آستانه‌هایی را برای موفقیت اولیه یا «رسیدن به سرعت گریز» (Escape Velocity) تعریف کرده‌اند. این آستانه‌ها عبارت‌اند از دریافت حداقل ۱۰ امتیاز در iOS، حداقل ۱۰۰ دانلود در اندروید و حداقل ۱۰ دانلود در کروم.نتایج نشان می‌دهند که سهم اپلیکیشن‌های عبورکننده از این آستانه‌ها در هر سه پلتفرم کاهش یافته است.البته این آستانه‌ها معیار موفقیت تجاری یا پایداری بلندمدت یک محصول نیستند؛ بلکه صرفاً نشانه‌هایی اولیه از میزان استقبال کاربران محسوب می‌شوند.پژوهش وضعیت سه پلتفرم را از سه منظر بررسی می‌کند: تعداد اپلیکیشن‌های جدید، میزان استقبال تجمعی کاربران و تغییر سهم اپلیکیشن‌ها بر اساس سطح استقبال.۱. رشد عرضه: تعداد اپلیکیشن‌های جدید در هر ماهدر ردیف نخست نمودار، تعداد اپلیکیشن‌های جدید منتشرشده در هر ماه نمایش داده شده است.در iOS، تعداد اپلیکیشن‌های جدید طی سال‌های ۲۰۲۱ تا ۲۰۲۵ عمدتاً در محدوده ۳۰ تا ۶۰ هزار اپلیکیشن در ماه قرار داشت. با این حال، در سال ۲۰۲۶ جهش چشمگیری رخ داده و این رقم به بیش از ۱۱۰ هزار اپلیکیشن در ماه رسیده است.در اندروید، روند متفاوتی مشاهده می‌شود. تعداد اپلیکیشن‌های جدید پس از یک دوره کاهش طولانی، از حدود ۱۵۰ هزار به نزدیک ۵۰ هزار اپلیکیشن در ماه رسیده بود؛ اما در ادامه، این روند معکوس شده و تعداد اپلیکیشن‌های جدید بار دیگر به حدود ۱۰۰ هزار اپلیکیشن در ماه افزایش یافته است.در کروم، افزایش عرضه از نظر نسبی چشمگیرتر است. تعداد اپلیکیشن‌های جدید از کمتر از ۵ هزار مورد در ماه به بیش از ۲۰ هزار مورد رسیده است.در مجموع، داده‌ها از افزایش قابل‌توجه ظرفیت تولید و انتشار اپلیکیشن حکایت دارند؛ افزایشی که در دوره گسترش ابزارهای کدنویسی مبتنی بر هوش مصنوعی شدت گرفته است.۲. تقاضای تجمعی: آیا کاربران نیز به همان نسبت افزایش یافته‌اند؟ردیف دوم نمودار، شاخص‌های استقبال از اپلیکیشن‌های جدید را بررسی می‌کند.در این بخش، منظور از «کوهورت» (Cohort)، گروهی از اپلیکیشن‌هاست که در یک بازه زمانی مشخص منتشر شده‌اند. پژوهشگران با بررسی میزان استقبال از هر گروه، تلاش کرده‌اند مشخص کنند آیا افزایش تعداد محصولات جدید با افزایش تقاضا نیز همراه بوده است یا خیر.در iOS، مجموع امتیازهای ثبت‌شده برای هر کوهورت عمدتاً حول یک میلیون نوسان می‌کند و با وجود جهش تعداد اپلیکیشن‌های جدید، روند صعودی پایداری در آن مشاهده نمی‌شود.در اندروید، مجموع دانلودهای هر کوهورت تقریباً در محدوده ۳۰۰ تا ۴۰۰ میلیون باقی مانده است. بنابراین، افزایش تعداد اپلیکیشن‌های منتشرشده با رشد متناسب دانلودها همراه نبوده است.در کروم، وضعیت متفاوت و حتی معکوس است. مجموع دانلودهای کوهورت‌ها از حدود ۲۰ میلیون در ابتدای دوره به محدوده ۲ تا ۵ میلیون کاهش یافته و سپس تقریباً در همان سطح باقی مانده است.این داده‌ها نشان می‌دهند که افزایش تعداد اپلیکیشن‌ها لزوماً به افزایش متناسب تقاضا منجر نشده است.البته باید توجه داشت که تعداد دانلود و تعداد امتیاز، معادل استفاده واقعی یا مستمر از یک اپلیکیشن نیستند. این شاخص‌ها بیشتر میزان استقبال اولیه را نشان می‌دهند و به‌تنهایی اطلاعات کافی درباره کاربران فعال، نرخ نگهداشت یا درآمد محصولات ارائه نمی‌کنند.۳. توزیع تقاضا: آیا همچنان اپلیکیشن‌های موفقی در میان محصولات جدید وجود دارند؟ممکن است استدلال شود که ثابت ماندن تقاضای کل، لزوماً به معنای کاهش موفقیت اپلیکیشن‌های جدید نیست. شاید تعداد دانلودها تغییر نکرده باشد، اما تقاضا میان محصولات جابه‌جا شده و گروهی از اپلیکیشن‌های جدید توانسته باشند سهم بیشتری از بازار را به دست آورند.پژوهشگران برای بررسی این احتمال، اپلیکیشن‌ها را بر اساس میزان استقبال کاربران به گروه‌های مختلف تقسیم کرده‌اند.در این تحلیل، اپلیکیشن‌های کم‌استقبال و اپلیکیشن‌هایی که از آستانه مشخصی از استقبال عبور کرده‌اند، به‌صورت جداگانه بررسی شده‌اند. سپس تغییر سهم هر گروه نسبت به ژانویه ۲۰۲۵ اندازه‌گیری شده است.نتایج در هر سه پلتفرم الگوی مشابهی را نشان می‌دهند:سهم اپلیکیشن‌های کم‌استقبال افزایش یافته است؛ در مقابل، سهم اپلیکیشن‌هایی که به آستانه استقبال اولیه می‌رسند، کاهش پیدا کرده است.در نمودار، خط سبز نشان‌دهنده گروه کم‌استقبال و خط قرمز نشان‌دهنده گروهی است که از آستانه تعریف‌شده عبور کرده‌اند.این واگرایی در کروم شدیدتر از دو پلتفرم دیگر است؛ به‌طوری‌که سهم گروه کم‌استقبال حدود ۱۵ واحد درصد افزایش یافته، در حالی که سهم گروه پراستقبال تقریباً ۱۵ واحد درصد کاهش پیدا کرده است.به بیان ساده‌تر، هرچند تعداد محصولات جدید افزایش یافته، نسبت کمتری از آن‌ها موفق شده‌اند حتی به سطح اولیه‌ای از استقبال کاربران دست پیدا کنند.۴. ارتباط این روند با عصر کدنویسی عامل‌محوردر نمودار، ناحیه‌ای با رنگ آبی مشخص شده است که از فوریه ۲۰۲۵ آغاز می‌شود و با عنوان «عصر کدنویسی عامل‌محور» (Agentic Coding Era) شناخته شده است.این بازه با گسترش ابزارهایی هم‌زمان است که می‌توانند با استفاده از هوش مصنوعی، بخش قابل‌توجهی از فرایند تولید نرم‌افزار را خودکار کنند؛ از نوشتن کد و رفع خطا گرفته تا پیاده‌سازی قابلیت‌ها و ساخت محصولات اولیه.داده‌های پژوهش نشان می‌دهند که واگرایی میان عرضه و تقاضا در این دوره تشدید شده است.با این حال، هم‌زمانی این دو پدیده به‌تنهایی رابطه علّی را اثبات نمی‌کند. برای تعیین میزان تأثیر مستقیم ابزارهای هوش مصنوعی بر افزایش عرضه یا تغییر الگوی تقاضا، به شواهد و تحلیل‌های تکمیلی نیاز است.مجموع این شواهد نشان می‌دهد که در وضعیت کنونی، افزایش توانایی تولید نرم‌افزار با افزایش متناسب موفقیت محصولات همراه نشده است.هوش مصنوعی و ابزارهای کدنویسی جدید، موانع فنی ساخت و انتشار اپلیکیشن را کاهش داده‌اند. در نتیجه، افراد بیشتری می‌توانند ایده‌های خود را به محصول تبدیل کنند و تعداد بیشتری اپلیکیشن وارد بازار می‌شود.اما سهولت ساخت محصول، به‌خودی‌خود به معنای وجود تقاضا برای آن نیست.پژوهش مورد بحث نشان می‌دهد که بخش فزاینده‌ای از اپلیکیشن‌های جدید، دست‌کم بر اساس شاخص‌های بررسی‌شده، موفق به جذب حداقلی از کاربران نمی‌شوند.این وضعیت را می‌توان در چارچوب پدیده‌ای بررسی کرد که گاهی از آن با عنوان «اپلیکیشن‌های کم‌ارزش و انبوه‌تولیدشده» یا App Slop یاد می‌شود؛ محصولاتی که ساخت آن‌ها آسان شده، اما ارزش یا جذابیت کافی برای جذب کاربران ندارند.البته داده‌های موجود به‌تنهایی ثابت نمی‌کنند که تمام این اپلیکیشن‌ها بی‌کیفیت یا فاقد ارزش‌اند. آنچه مستقیماً از پژوهش برمی‌آید، افزایش عرضه، رشد نکردن متناسب شاخص‌های تقاضا و کاهش سهم محصولاتی است که به آستانه مشخصی از استقبال اولیه دست پیدا می‌کنند.بنابراین، نتیجه اصلی این است که کاهش هزینه تولید نرم‌افزار، مسئله دشوارترِ ساخت محصولی که کاربران واقعاً به آن نیاز داشته باشند را حل نکرده است.چرا این نتایج چندان شگفت‌آور نیستند؟گزارش سه دلیل اصلی را برای قابل‌انتظار بودن این وضعیت مطرح می‌کند.نخست، ساخت یک محصول موفق همواره چیزی فراتر از نوشتن کد بوده است.تولید نرم‌افزار تنها یکی از اجزای فرایند خلق محصول است. شناسایی یک مسئله واقعی، درک نیاز کاربران، طراحی تجربه کاربری مناسب، ایجاد اعتماد، توزیع محصول، جذب مشتری و حفظ کاربران، همگی در موفقیت یک اپلیکیشن نقش دارند.ابزارهای هوش مصنوعی می‌توانند هزینه و زمان پیاده‌سازی فنی را به‌شدت کاهش دهند، اما لزوماً مشکلات مربوط به تناسب محصول با بازار (Product-Market Fit)، توزیع، بازاریابی و نگهداشت کاربران را برطرف نمی‌کنند.برای مثال، ممکن است یک توسعه‌دهنده با کمک هوش مصنوعی بتواند ظرف چند ساعت محصولی بسازد که پیش‌تر توسعه آن به چند هفته زمان نیاز داشت. با این حال، اگر آن محصول مسئله مهمی را حل نکند یا راهی مؤثر برای دسترسی به کاربران هدف نداشته باشد، سرعت بیشتر در توسعه تأثیر چندانی بر موفقیت نهایی آن نخواهد داشت.دوم، هنوز برای قضاوت قطعی درباره پیامدهای بلندمدت این تحول زود است.گسترش ابزارهای کدنویسی مبتنی بر هوش مصنوعی پدیده‌ای نسبتاً جدید است و بازار هنوز در حال سازگار شدن با آن است.ممکن است در مراحل اولیه، بخش بزرگی از محصولات ساخته‌شده صرفاً آزمایشی باشند. در ادامه، با افزایش تجربه توسعه‌دهندگان، بلوغ ابزارها و شکل‌گیری مدل‌های جدید توزیع و کسب‌وکار، الگوی عرضه و تقاضا نیز تغییر کند.بنابراین، داده‌های فعلی بیشتر تصویری از وضعیت کنونی بازار ارائه می‌کنند و نباید آن‌ها را به‌عنوان حکمی قطعی درباره آینده نرم‌افزارهای مبتنی بر هوش مصنوعی در نظر گرفت.سوم، پیشی گرفتن عرضه از تقاضا در مراحل اولیه یک تحول فناورانه طبیعی است.زمانی که فناوری جدیدی هزینه تولید را کاهش می‌دهد، افراد بیشتری به آزمایش ایده‌های خود روی می‌آورند.بخش قابل‌توجهی از این فعالیت‌ها، نوعی آزمون‌وخطا و تجربه‌ورزی فردی (Amateur Tinkering) است. افراد محصولاتی می‌سازند تا قابلیت‌های فناوری را کشف کنند، مهارت‌های جدید بیاموزند یا ایده‌های شخصی خود را آزمایش کنند؛ حتی اگر تقاضای مشخصی برای آن محصولات وجود نداشته باشد.در چنین شرایطی، طبیعی است که عرضه در کوتاه‌مدت سریع‌تر از تقاضا رشد کند.این افزایش فعالیت می‌تواند هم‌زمان دو پیامد داشته باشد: از یک سو، تعداد زیادی محصول با استقبال اندک وارد بازار می‌شوند؛ از سوی دیگر، هزینه پایین‌تر آزمایش ایده‌ها ممکن است زمینه کشف نیازهای جدید و شکل‌گیری محصولات ارزشمند را فراهم کند.در نتیجه، افزایش اپلیکیشن‌های کم‌استقبال را می‌توان هم نشانه‌ای از اشباع نسبی بازار و هم بخشی از فرایند آزمون‌وخطا در دوره گذار به شیوه‌های جدید تولید نرم‌افزار دانست.جمع‌بندی نهایی: هوش مصنوعی در حال تغییر اقتصاد تولید نرم‌افزار است، اما هنوز شواهد کافی وجود ندارد که نشان دهد رشد ظرفیت تولید، به همان نسبت به رشد تقاضا یا موفقیت محصولات منجر شده است. آنچه تغییر کرده، سهولت ساخت اپلیکیشن است؛ آنچه همچنان دشوار باقی مانده، شناسایی یک نیاز واقعی، خلق ارزش برای کاربر و تبدیل محصول به کسب‌وکاری پایدار است.</description><category>Amir Mokarchi</category><author>Amir Mokarchi</author><pubDate>Sun, 20 Sep 2026 13:40:17 +0330</pubDate></item><item><title>داستان مشارکت من در OpenAI.NET</title><link>https://virgool.ir/@mokarchi/داستان-مشارکت-من-در-openainet-ecvvi1zh7qyh</link><description>نوع خاصی از سکوت وجود دارد که وقتی برای اولین بار یک کدبیس (Codebase) بزرگ را باز می‌کنید، شما را فرا می‌گیرد. مخزن کد (Repository) درست مقابل شماست. سیستم پیگیری مشکلات (Issue Tracker) عمومی است. هر کلاس، تست، Pull Request و بحث‌های مربوط به طراحی برای خواندن در دسترس است. از نظر فنی، هیچ چیزی مانع مشارکت شما نیست. با این حال، فاصله بین «خواندن کد» و «تغییر دادن کد» بسیار زیاد به نظر می‌رسد. این دقیقاً همان حسی بود که وقتی شروع به کار روی SDK رسمی OpenAI برای .NET کردم، داشتم. این پروژه متعلق به مایکروسافت نیست، اما عمیقاً در اکوسیستم .NET مایکروسافت جای گرفته است: قراردادهای API عمومی، تجربه تزریق وابستگی (DI)، مدل پیکربندی و معماری کلاینت آن، همگی به شدت با الگوهای مورد استفاده در سراسر .NET و Azure SDK مرتبط هستند. به عبارت دیگر، این دقیقاً همان نوع کدبیسی بود که می‌توانست «سندروم ایمپاستر» را تحریک کند. من کی بودم که بخواهم یک تجربه جدید از تزریق وابستگی را برای کتابخانه‌ای پیشنهاد دهم که توسعه‌دهندگان در سراسر جهان از آن استفاده می‌کنند؟ اگر معماری را اشتباه فهمیده بودم چه؟ اگر Pull Request من به جای ارزش‌آفرینی، فقط باعث شلوغی کد می‌شد چه؟ اگر نگهداران پروژه (Maintainers) به پیاده‌سازی من نگاه می‌کردند و فوراً ده مشکل را می‌دیدند که من نادیده گرفته بودم چه؟ این سؤالات قبل از شروع من ناپدید نشدند. اما من با وجود آن‌ها، شروع کردم. آنچه در ادامه آمد، یک داستان سریع از نوع «ارسال PR، دریافت تایید و ادغام (Merge)» نبود. این تبدیل به سفری تقریباً پنج‌ماهه شد؛ از اولین Pull Request در ۱۸ سپتامبر ۲۰۲۵ تا ادغام نهایی در ۲۵ فوریه ۲۰۲۶. کدها تغییر کردند. طراحی عوض شد. محدوده کار گسترش یافت. در حالی که یک طراحی جامع‌تر برای اکوسیستم در حال شکل‌گیری بود، PR من متوقف شد. سپس دوباره زنده شد، چندین دور بررسی (Review) را پشت سر گذاشت، موانع نهایی CI را رد کرد و در نهایت به آن آیکون بنفش کوچکی رسید که هر مشارکت‌کننده‌ای آن را به خاطر می‌سپارد. این داستان Pull Request شماره ۶۹۶ است؛ و داستانی از اینکه چگونه آموختم یک مشارکت موفق در متن‌باز، به‌ندرت فقط به نوشتن نسخه اول کد محدود می‌شود.تجربه‌ای که می‌خواستم برای توسعه‌دهندگان بهبود ببخشم، برای تقریباً هر توسعه‌دهنده ASP.NET Core آشنا بود: ثبت (Register) کلاینت‌های OpenAI در کانتینر داخلی Dependency Injection. در یک اپلیکیشن، توسعه‌دهندگان می‌خواهند پیکربندی کلاینت طبیعی به نظر برسد. آن‌ها می‌خواهند تنظیمات را در appsettings.json قرار دهند، اسرار (Secrets) را از طریق متغیرهای محیطی بازنویسی کنند، سرویس‌ها را هنگام استارت‌آپ ثبت کنند و کلاینت‌های Typed را هر جا که نیاز است تزریق کنند. نسخه ساده‌شده‌ای از تجربه مورد نظر به این شکل بود:builder.AddChatClient(&#34;Chat&#34;);&#xA;public sealed class MyService(ChatClient chatClient)&#xA;{&#xA;    // Use chatClient...&#xA;}هدف، توضیح دادنش آسان بود: کلاینت‌های OpenAI را به‌گونه‌ای بسازیم که به‌طور طبیعی با قراردادهای پیکربندی و DI که توسعه‌دهندگان .NET از قبل می‌شناسند، سازگار باشند.اما «آسان بودن در توضیح»، با «آسان بودن در طراحی» یکی نیست. اولین پیاده‌سازی من مستقیماً به سراغ مشکل رفت. اولین کامیت من شامل متدهای Extension برای IServiceCollection بود، یک نوع Options تعریف کردم، پشتیبانی از پیکربندی و متغیرهای محیطی را اضافه کردم و مستندات و تست‌های واحد (Unit Tests) را نوشتم. این راهکار برای هر کسی که یک یکپارچه‌سازی (Integration) در ASP.NET Core انجام داده بود، کاربردی و آشنا بود. من کارها را در محیط محلی انجام داده بودم. کدهای اطراف را خوانده بودم. تست‌ها را اضافه کرده بودم و مستندات را نوشته بودم. اما در یک لحظه، آماده‌سازی باید تمام شود. شما باید کارتان را در معرض دید دیگران قرار دهید. هنوز تردیدی را که قبل از کلیک روی دکمه Create Pull Request داشتم به یاد می‌آورم. خود دکمه بی‌ضرر است، اما آنچه نمایندگی می‌کند، نیست. این دکمه، استدلال‌های خصوصی شما را به یک پیشنهاد عمومی تبدیل می‌کند. می‌گوید: «من معتقدم این کد متعلق به اینجاست.» سپس روی آن کلیک کردم.اولین بررسی، بزرگ‌تر از کد من بودیکی از اولین درس‌ها تقریباً بلافاصله رسید: نگهداران پروژه، یک مشارکت را فقط به عنوان تکه کدی که «کار می‌کند» بررسی نمی‌کنند. آن‌ها آن را به عنوان بخشی دائمی از یک اکوسیستم می‌بینند. «استیون توب» (Stephen Toub) یک سؤال بنیادی مطرح کرد: آیا این تجربه باید در SDK اصلی باشد یا باید توسط Aspire مدیریت شود؟ «کریستوف کوالینا» (Krzysztof Cwalina) اضافه کرد که مدل پیکربندی باید با کارهای موجود در Aspire، .NET و Azure همسو باشد. نگرانی آن‌ها این نبود که DI بی‌اهمیت است؛ بلکه این بود که چندین تیم در حال حل مشکلات مشابه بودند و یک راهکار محلی (Local) ممکن بود به‌طور اتفاقی یک قرارداد جدید ایجاد کند، به جای اینکه به یک قرارداد مشترک بپیوندد. این موضوع ماهیت بحث را تغییر داد. من با یک سؤال پیاده‌سازی آمده بودم: «آیا این کد کار می‌کند؟»؛ اما نگهداران پروژه سؤالی اکوسیستمی می‌پرسیدند: «آیا این انتزاع (Abstraction) درست است، در لایه درست قرار دارد و از الگوی بلندمدت صحیحی استفاده می‌کند؟»؛ این‌ها دو سؤال بسیار متفاوت هستند. برای یک مشارکت‌کننده، این لحظه‌ای آسیب‌پذیر است. راحت است که بازخوردهای معماری را به عنوان قضاوتی شخصی ترجمه کنیم: «راهکار من رد شد، پس من به اندازه کافی خوب نبودم.» اما این تفسیر، چیزی را که نگهداران پروژه از آن محافظت می‌کنند نادیده می‌گیرد. یک SDK که به‌طور گسترده استفاده می‌شود، بهای هر انتزاع عمومی را برای سال‌ها می‌پردازد. وقتی یک API منتشر می‌شود، تغییر دادن آن بسیار دشوارتر از تغییر دادن یک Pull Request است. بازخورد این نبود که «نباید تلاش می‌کردی»، بلکه این بود که «این ایده با طراحی‌ای بزرگ‌تر از این مخزن کد در ارتباط است».در اول اکتبر، «جسی اسکوایر» (Jesse Squire) توضیح داد که تیم هنوز در حال تعریف الگوهای مشترک برای ثبت، ساخت، پیکربندی کلاینت و همسویی با اکوسیستم گسترده‌تر .NET است. بدون یک طراحی کاملاً مدون، تیم هنوز نمی‌توانست راهنمایی‌های دقیقی برای پیشبرد پیاده‌سازی ارائه دهد. او سه گزینه پیشنهاد داد: بستن PR، بازگشت به آن در آینده با یک پیاده‌سازی جدید، یا متوقف کردن (Park) آن و همکاری پس از آماده شدن طراحی. من گزینه متوقف کردن را انتخاب کردم. این تصمیم در نهایت یکی از مهم‌ترین بخش‌های این مشارکت شد. پاسخ دادم که خوشحال می‌شوم منتظر بمانم، کد را بازبینی کنم و پیاده‌سازی را با الگوهای گسترده‌تر همسو کنم. «مایکل نش» (Michael Nash) موافقت کرد که این بهترین مسیر است و گفت وقتی طراحی آماده شد، می‌توانیم همکاری کنیم. برای چندین ماه، Pull Request باز ماند اما به‌طور عمدی متوقف شد. در ابتدا، این حسِ درجا زدن را داشت؛ اما در نگاه به گذشته، این هم بخشی از کار بود.متن‌باز یعنی دانستن اینکه چه زمانی باید منتظر ماندتوسعه‌دهندگان آموزش دیده‌اند که برای «حرکت» ارزش قائل شوند. ما تیکت‌ها را می‌بندیم، کامیت‌ها را Push می‌کنیم، تست‌های شکست‌خورده را کم می‌کنیم و پیشرفت را با تغییرات قابل مشاهده می‌سنجیم. انتظار کشیدن، غیربهره‌ور به نظر می‌رسد. اما پروژه‌های بالغ متن‌باز در مقیاس متفاوتی عمل می‌کنند. یک مشارکت ممکن است به هماهنگی بین چندین مخزن کد، تیم‌های فریم‌ورک، مالکان طراحی، زمان‌بندی‌های انتشار و فرآیندهای بررسی API وابسته باشد. بهترین اقدام بعدی گاهی یک کامیت دیگر نیست؛ بلکه حفظ گفتگو تا زمانی است که پروژه آماده اتخاذ تصمیم درست باشد.متوقف کردن PR سه چیز به من آموخت:۱. تأخیر نگهدارنده پروژه لزوماً به معنای بی‌علاقگی نیست؛ بلکه ممکن است بازتابی از هماهنگی‌هایی باشد که از بیرون دیده نمی‌شوند.۲. زنده نگه داشتن یک مشارکت به معنای درخواست مکرر برای توجه نیست؛ بلکه به معنای در دسترس بودن، ارتباط محترمانه و آمادگی در لحظه‌ای است که طراحی قابل اجرا شود.۳. مالکیت کد و مالکیت ایده متفاوت است. من مشارکت را شروع کرده بودم، اما طراحی نهایی باید متعلق به پروژه و کاربرانش می‌بود، نه متعلق به اولین پیاده‌سازی من.نکته آخر از همه مهم‌تر بود. اگر من از نظر عاطفی به کد اولیه دلبستگی پیدا می‌کردم، از چیز اشتباهی دفاع می‌کردم. هدف این نبود که «دقیقاً پیاده‌سازی من» ادغام شود؛ هدف این بود که تجربه توسعه‌دهنده .NET به‌گونه‌ای بهبود یابد که نگهداران پروژه بتوانند در بلندمدت از آن پشتیبانی کنند.بازگشت Pull Request به زندگینقطه عطف با [Issue شماره ۹۳۲: &#34;OpenAI: Add Configuration and DI Support&#34;] رسید. این Issue، کارهای SDK OpenAI را به طراحی پیکربندی و DI در System.ClientModel متصل کرد. مستندات طراحی Azure SDK، یک مدل قابل استفاده مجدد برای تنظیمات کلاینت متصل به پیکربندی (Configuration-bound)، ثبت‌های DI معمولی و Keyed، حل اعتبارنامه‌ها (Credential Resolution)، گزینه‌های کلاینت تودرتو و مراجع پیکربندی مشترک را توصیف می‌کرد. این همان لحظه‌ای بود که معماری در ذهنم جا افتاد. وظیفه دیگر «اضافه کردن چند متد کمکی برای ثبت سرویس‌های خاص OpenAI» نبود؛ بلکه «ترجمه یک الگوی مشترک Client-Model به ساختار عینی SDK OpenAI» بود.این تفاوت شاید ظریف به نظر برسد، اما تقریباً همه چیز را تغییر داد.پیاده‌سازی اولیه من بر ثبت مستقیم در IServiceCollection و یک شیء Options مخصوص OpenAI متمرکز بود. طراحی بازنگری‌شده بر مفاهیم زیر متمرکز شد:    هر کلاینت تخصصی، کلاس ClientSettings با تایپ قوی (Strongly Typed) مخصوص به خود را دریافت می‌کند.    ویژگی‌های آن کلاس تنظیمات، بازتاب‌دهنده پارامترهای سازنده (Constructor) اصلی کلاینت است.    رفتار اعتبارنامه‌ها از مدل تنظیمات پایه مشترک می‌آید، به جای اینکه در هر تایپ مشتق شده دوباره اختراع شود.    هر کلاینت سازنده‌ای می‌گیرد که شیء تنظیمات آن را می‌پذیرد.    ثبت سرویس‌ها از IHostApplicationBuilder و زیرساخت عمومی System.ClientModel استفاده می‌کند.    هر دو نوع ثبت معمولی و Keyed پشتیبانی می‌شوند تا امکان داشتن چندین کلاینت از یک نوع با پیکربندی‌های متفاوت فراهم شود.به عنوان مثال، ChatClient سازنده‌ای داشت که حول مدل، سیاست احراز هویت و گزینه‌های کلاینت شکل گرفته بود. بنابراین، تایپ تنظیمات آن باید بخش‌های قابل پیکربندی آن سازنده را نمایندگی می‌کرد:[Experimental(&#34;SCME0002&#34;)]&#xA;public sealed class ChatClientSettings : ClientSettings&#xA;{&#xA; public string? Model { get; set; }&#xA; public OpenAIClientOptions? Options { get; set; }&#xA; protected override void BindCore(IConfigurationSection section)&#xA; {&#xA; // Bind client-specific configuration.&#xA; }&#xA;}پیاده‌سازی دقیق در طول بررسی تکامل یافت، اما اصل معماری اکنون روشن بود: تنظیمات (Settings) باید کلاینت را توصیف کنند، در حالی که مدل مشترک کلاینت (Shared Client Model) باید مکانیسم‌های مشترک پیکربندی و DI را فراهم کند.[Experimental(&#34;SCME0002&#34;)]&#xA;public ChatClient(ChatClientSettings settings)&#xA; : this( settings.Model, AuthenticationPolicy.Create(settings), settings.Options)&#xA;{&#xA;}این لحظه «یافتم!» (Aha!) من بود. دیگر مجموعه‌ای از متدهای Extension ایزوله را نمی‌دیدم، بلکه SDK را به عنوان یکی از شرکت‌کنندگان در یک اکوسیستم بزرگ‌تر کلاینت‌های .NET می‌دیدم.حرکت سریع و کشف اینکه طراحی هنوز در حال حرکت استوقتی مسیر مشخص شد، سریع حرکت کردم. شاید بیش از حد سریع. در ۵ فوریه، PR را بر اساس Issue شماره ۹۳۲ به‌روز کردم و درخواست بررسی دادم. مایکل پاسخ داد که من سریع‌تر از آمادگی او شروع کرده‌ام چون آن Issue هنوز تمام جزئیات پیاده‌سازی را شامل نمی‌شد. او راهنمایی‌های ناقص را به‌روز کرد. این تعامل چیزی را نشان داد که بعدها در این همکاری قدر بدانم: نگهدارنده پروژه صرفاً آنچه ناقص بود را رد نکرد، بلکه طراحی را شفاف کرد و من پیاده‌سازی را اصلاح کردم. رابطه ما کمتر شبیه «ارسال‌کننده در مقابل دروازه‌بان» و بیشتر شبیه دو توسعه‌دهنده شد که برای رسیدن به یک نتیجه مشترک تلاش می‌کنند. تا ۷ فوریه، جزئیات تکمیلی را اعمال کردم و PR را برای بررسی فرستادم. سپس تکرارهای (Iterations) واقعی شروع شد.آزمونی سخت: یادگیری از طریق بررسی (Review)کامنت‌های بررسی مفصل بودند، اما به‌طور چشم‌گیری آموزنده هم بودند. هر کدام اصلی را آشکار می‌کردند که فراتر از آن خط کد بود که در موردش بحث می‌شد.یک منبع واحد برای حقیقتِ اعتبارسنجی (Validation Truth)در سازنده یکی از کلاینت‌ها، من چک کردن پارامترها و رفتارهای جایگزینی (Fallback) را تکرار کرده بودم که قبلاً در سازنده اصلی وجود داشت. مایکل اشاره کرد که سازنده اصلی مالک این اعتبارسنجی است و سازنده جدیدِ مبتنی بر Settings باید اجازه دهد سازنده اصلی کارش را انجام دهد. درس بزرگتر از حذف چند خط کد بود: اورلودهای سازنده باید به یک مسیر اعتبارسنجی واحد ختم شوند، به جای اینکه تعاریف موازی از وضعیت معتبر (Valid State) ایجاد کنند. اعتبارسنجی تکراری هنگام نوشتن حس امنیت می‌دهد، اما در طول زمان باعث ایجاد «انحراف» (Drift) می‌شود. یک سازنده مقداری را می‌پذیرد که دیگری رد می‌کند. یکی مقدار پیش‌فرض را می‌دهد و دیگری فراموش می‌کند. متمرکز کردن قوانین ساخت، استدلال درباره رفتار کد و نگهداری آن را آسان‌تر می‌کند.نام‌های پیکربندی بخشی از اپلیکیشن کاربر هستندمن نام‌های پیش‌فرض برای بخش‌های پیکربندی (Configuration Sections) در متدهای ثبت قرار داده بودم. بررسی‌ها این فرض را به چالش کشید. یک توسعه‌دهنده ممکن است به دو کلاینت چت نیاز داشته باشد که هر کدام مدل، Endpoint یا اعتبارنامه متفاوتی دارند. نام بخش‌ها می‌تواند PrimaryChat یا PremiumChat یا هر چیز دیگری باشد که برای آن اپلیکیشن معنا دارد. حذف پیش‌فرض‌ها صرفاً یک ترجیح در سبک API نبود؛ بلکه انتخاب کاربر را حفظ می‌کرد و سناریوهای چندکلاینتی را به‌طور طبیعی پشتیبانی می‌کرد. این بینش مستقیماً به ثبت Keyed وصل شد:builder.AddKeyedChatClient(&#34;primary&#34;, &#34;PrimaryChat&#34;);&#xA;builder.AddKeyedChatClient(&#34;premium&#34;, &#34;PremiumChat&#34;);طراحی فقط برای این نبود که ثبت یک کلاینت آسان شود، بلکه برای این بود که کل خانواده‌ای از توپولوژی‌های استقرار واقعی امکان‌پذیر شوند.اجتناب از جفت‌شدگی اتفاقی (Accidental Coupling)در پیاده‌سازی بازنگری‌شده، ابتدا یک لایه مشترک OpenAISpecializedClientSettings معرفی کردم. به نظر می‌رسید راهی منطقی برای کاهش تکرار باشد. مایکل پیشنهاد داد که هر کلاس تنظیمات مستقیماً از ClientSettings ارث‌بری کند، زیرا لایه اضافی مخصوص OpenAI، کلاینت‌های تخصصی را بیش از حد نیاز به هم جفت (Couple) می‌کند. این یک یادآوری ارزشمند بود: «حذف تکرار» لزوماً به معنای «طراحی خوب» نیست. گاهی اوقات مقدار کمی ساختار تکراری، ارزان‌تر از یک انتزاع مشترک است که تایپ‌های غیرمرتبط را مجبور می‌کند با هم تکامل یابند.منطق Bind کردن را جایی قرار دهید که داده‌ها درک شوندمنطق Bind کردن پیکربندی برای OpenAIClientOptions ابتدا خارج از نوع Options بود. در بررسی‌ها، این منطق به یک سازنده داخلی در OpenAIClientOptions منتقل شد که یک IConfigurationSection می‌پذیرفت. باز هم، این فقط سازماندهی فایل نبود. این کار باعث شد تفسیر داده‌ها در کنار شیئی قرار بگیرد که معنا و اعتبارسنجی آن مقادیر را درک می‌کند.کامل بودن، بخشی از سازگاری استدر دور اول، من کلاینت‌های تخصصی بدیهی را پوشش دادم: چت، embeddings، صدا، تصویر و نظارت (Moderation). سپس در بررسی متوجه شدم که SDK انواع بسیار بیشتری از کلاینت‌ها را دارد: assistants، batches، containers و غیره. اگر این ویژگی فقط برای زیرمجموعه‌ای از کلاینت‌ها منتشر می‌شد، توسعه‌دهندگان با یک SDK ناسازگار مواجه می‌شدند: یک کلاینت را می‌شد با الگوی جدید پیکربندی کرد، اما دیگری هنوز نیاز به ساخت دستی داشت. بنابراین محدوده کار گسترش یافت. در نسخه نهایی، Pull Request بیش از چهل فایل را تغییر داده بود. آنچه به عنوان چند متد کمکی DI شروع شده بود، به یک قابلیت سیستماتیک در تمام خانواده کلاینت‌ها تبدیل شد. این گسترش، «خزش محدوده» (Scope Creep) نبود؛ بلکه نتیجه طبیعی درک درست معماری بود.لحظه‌ای که لحن بازخوردها تغییر کرددر بررسی‌های طولانی، لحظه ظریف اما مشخصی وجود دارد که گفتگو تغییر می‌کند. در ابتدا، کامنت‌ها شکل طراحی را به چالش می‌کشند. بعداً، جزئیات را اصلاح می‌کنند. سؤالات از «آیا این انتزاع باید وجود داشته باشد؟» به «آیا می‌توانیم این عبارت را صریح‌تر کنیم؟» یا «آیا این متدها می‌توانند به ترتیب الفبایی باشند؟» تغییر می‌کنند. در ۱۰ فوریه، پس از اینکه تغییرات معماری اعمال شد، مایکل نوشت که فقط یک به‌روزرسانی جزئی باقی مانده و کارها خوب به نظر می‌رسند. دو روز بعد، در بررسی‌اش نوشت: &#34;Changes LGTM, thanks again.&#34; (تغییرات از نظر من عالی است، باز هم ممنون). برای یک مشارکت‌کننده، این چند کلمه وزن زیادی دارند. به این معنی نیست که کار تمام شده، اما یعنی ایده اصلی از یک مرز مهم عبور کرده است. کد دیگر به عنوان یک پیشنهاد خارجی ارزیابی نمی‌شود، بلکه شروع به شبیه شدن به بخشی از پروژه می‌کند. سپس بررسی دیگری رسید. Copilot نبودِ چک کردن‌های null را در سازنده‌های جدید شناسایی کرد و درخواست پوشش تستی برای Bind کردن پیکربندی و ثبت‌های معمولی و Keyed داد. José Harriaga این یافته‌ها را بررسی کرد و پیشنهاد داد در جاهایی که اعتبارسنجی و مقداردهی صریح منجر به مسیر ساخت شفاف‌تر و امن‌تری می‌شود، زنجیره‌سازی سازنده‌ها (Constructor Chaining) حذف شود. او همچنین خواست متدهای ثبت به صورت سازگار مرتب شوند تا نگهداران آینده راحت‌تر کلاینت‌های جا مانده را شناسایی کنند. Pull Request دوباره به وضعیت &#34;Changes Requested&#34; بازگشت. در ابتدای این مسیر، شاید این حس عقب‌نشینی می‌داد. اما در آن زمان، من متفاوت فکر می‌کردم. تایید نهایی، خط پایان نیست اگر بررسی‌کننده دیگری یک شکاف واقعی پیدا کند. کد آنقدر بهبود یافته بود که سطح عمیق‌تری از بررسی را جذب کند. من تغییرات را اعمال کردم و از خوزه برای بررسی دقیقش تشکر کردم.کیلومتر آخر، باشکوه نبودبخش نهایی یک مشارکت متن‌باز اغلب کمتر از کارهای معماری، سینمایی است. لیست‌های API تولیدشده (Generated) باید به‌روز می‌شدند. یک اسکریپت مخزن (Export-Api.ps1) بود که باید اجرا می‌شد. حتی بعد از اینکه فکر می‌کردم فایل‌های API به‌روز هستند، CI هنوز شکست می‌خورد. برنچ‌های تکمیلی و PRهای نگهداران پروژه برای هماهنگی وجود داشت. دوباره درخواست شد که API Surface بازتولید شود. اسکریپت را دوباره اجرا کردم اما تغییری ایجاد نشد. مایکل با PRهای کوچک روی فورک (Fork) من، به حل مسائل مربوط به وضعیت مخزن کمک کرد. این بخش از داستان مهم است چون مشارکت در سطح کیفیت تولیدی (Production-quality)، فقط بحث‌های ظریف معماری نیست. بلکه شامل این موارد است:    درک اسکریپت‌های Build خاص پروژه؛    همگام نگه داشتن فایل‌های API عمومی تولید شده؛    پاسخ شفاف وقتی نتایج محلی و نتایج CI با هم نمی‌خوانند؛    پذیرفتن کمک وقتی نگهداران پروژه می‌توانند سریع‌تر مشکلات خاص مخزن را حل کنند؛    و درگیر ماندن حتی بعد از اینکه کارهای «جالب» کدنویسی تمام شده است.در ۲۵ فوریه، مایک PR را تایید کرد و از خوزه خواست برای آخرین بار نگاهی بیندازد. خوزه در ساعت ۰۹:۰۱ UTC آن را تایید کرد. یک دقیقه بعد، Pull Request شماره ۶۹۶ ادغام شد .نشان بنفشگیت‌هاب یک Pull Request ادغام شده را با یک آیکون بنفش کوچک نشان می‌دهد. از نظر بصری، تقریباً هیچ است. اما از نظر عاطفی، کل این سفر را در خود جای داده است. شامل اضطراب قبل از اولین ارسال. سؤالات اولیه معماری. لحظه‌ای که PR برای جلوگیری از ادغام اتفاقی متوقف شد. انتخابِ متوقف کردن کار به جای رهای کردن آن. ماه‌ها انتظار. Issue طراحی جدید. بازنویسی کد. بررسی‌های دقیق مایکل. بررسی‌های گسترده‌تر خوزه. شکست‌های CI. فایل‌های API تولید شده. تاییدات نهایی و از همه مهم‌تر، شامل تغییر در دیدگاه من است. وقتی PR را باز کردم، فکر می‌کردم موفقیت یعنی ثابت کنم راهکار اولیه من «به اندازه کافی خوب» است. وقتی ادغام شد، فهمیدم موفقیت یعنی کمک به پروژه برای رسیدن به «راهکار درست» حتی اگر این کار مستلزم جایگزینی بخش بزرگی از رویکرد اول من باشد.اثر موجی: مشارکتی فراتر از یک متد کمکیویژگی نهایی، یک میان‌بر DI ایزوله و مخصوص OpenAI نبود. بلکه الگویی را پیاده کرد که به System.ClientModel (زیرساخت مشترک کلاینت‌ها در Azure SDK) متصل بود.این طراحی گسترده‌تر قابلیت‌هایی چون موارد زیر را پشتیبانی می‌کند:    تنظیمات با تایپ قوی که از پیکربندی بارگذاری می‌شوند؛    گزینه‌های تودرتو برای Pipeline، Retry، Endpoint، Logging و کلاینت؛    اعتبارنامه‌هایی که از طریق پیکربندی یا Resolvers خارجی تامین می‌شوند؛    ثبت‌های معمولی و Keyed کلاینت؛    چندین نمونه از یک نوع کلاینت؛    و سینتکس مرجع برای به اشتراک گذاشتن پیکربندی بین کلاینت‌ها.بنابراین اثر موجی در هر دو جهت بود. طراحی گسترده‌تر .NET و Azure SDK، PR من را شکل داد و SDK دات‌نت OpenAI به یک پذیرنده عینی (Concrete Adopter) برای آن طراحی در تمام کلاینت‌های تخصصی‌اش تبدیل شد. این نتیجه‌ای بسیار معنادارتر از اضافه کردن چند متد کمکی است. این کار «سازگاری» (Consistency) ایجاد می‌کند. توسعه‌دهنده دات‌نتی که این الگو را در یک کتابخانه کلاینت یاد می‌گیرد، می‌تواند آن را در جای دیگر هم شناسایی کند. نگهداران پروژه یک مدل مشترک به دست می‌آورند. انواع کلاینت‌های آینده، مسیر گسترش شفافی دارند. این تجربه طرز فکر من را درباره معماری تغییر داد: گاهی اوقات باارزش‌ترین مشارکت، اختراع یک انتزاع منحصربه‌فرد نیست، بلکه شناسایی یک انتزاع مشترک و پیاده‌سازی وفادارانه آن در یک زمینه جدید است.دستاوردهای فنی که با خود خواهم داشتاین بررسی‌ها درس‌هایی را به من داد که اکنون آن‌ها را به عنوان اصول مهندسی قابل استفاده می‌بینم:    API عمومی را برای اکوسیستم طراحی کنید، نه فقط برای یک مثال فوری. متد ثبت کلاینتی که برای یک کلاینت پیش‌فرض کار می‌کند، ممکن است زمانی که اپلیکیشن به چندین نمونه با پیکربندی متفاوت نیاز دارد، شکست بخورد.    اورلودها را از طریق یک مدل ساخت و اعتبارسنجی واحد هدایت کنید. تکرار اعتبارسنجی در سازنده‌ها باعث ایجاد ناسازگاری‌های ظریف می‌شود.    فقط برای حذف تکرار، از ارث‌بری استفاده نکنید. یک تایپ پایه مشترک می‌تواند تبدیل به یک جفت‌شدگی (Coupling) ناخواسته بین کلاینت‌هایی شود که در حالت عادی مستقل هستند.    منطق Bind کردن را نزدیک به تایپی قرار دهید که معنای مقادیر را درک می‌کند. پارس کردن پیکربندی، مقادیر پیش‌فرض و اعتبارسنجی نباید در کلاس‌های Extension غیرمرتبط پخش شوند.    سازگاری مستلزم پوشش کامل است. اگر یک ویژگی از نظر مفهومی برای خانواده‌ای از کلاینت‌ها کاربرد دارد، پیاده‌سازی جزئی می‌تواند یک ظاهر عمومی گیج‌کننده ایجاد کند.    تزریق وابستگی Keyed یک مورد استثنایی (Edge Case) نیست. داشتن چندین مدل، Endpoint، Tenant یا اعتبارنامه، از الزامات عادی محیط Production است.    تست‌ها باید تجربه توسعه‌دهنده را تأیید کنند، نه صرفاً ثبت سرویس را. دیدن یک Service Descriptor در کانتینر کافی نیست؛ Bind شدن پیکربندی و کلاینت‌های Resolve شده باید درست عمل کنند.    آرتیفکت‌های تولید شده API بخشی از قرارداد هستند. خطوط پایه API عمومی و اسکریپت‌های Export لایق همان توجهی هستند که به کدهای دست‌نویس می‌شود.آنچه درباره ارتباطات آموختمدرس‌های فنی فقط نیمی از ماجرا بود. این مشارکت به من آموخت که «ارتباطات» بخشی از «پیاده‌سازی» است. یاد گرفتم که وضعیت کار را بپرسم بدون اینکه تصور کنم نادیده گرفته شده‌ام. یاد گرفتم تفاوت بین «طراحی متوقف شده» و «مشارکت‌کننده رد شده» را تشخیص دهم. یاد گرفتم وقتی تغییرات آماده است به وضوح بیان کنم، آنچه را که تست کرده‌ام خلاصه کنم و آنچه را که هنوز خراب است توصیف کنم. یاد گرفتم که یک پاسخ کوتاه مانند «خوشحال می‌شوم وقتی طراحی آماده شد، کد را بازبینی کنم» می‌تواند ماه‌ها همکاری آینده را حفظ کند. ارتباطات خوب در متن‌باز نه منفعل است و نه مطالبه‌گر؛ بلکه دقیق، صبور و متمرکز بر «مالکیت مشترک» است. بهترین تبادلات در PR، تراکنش‌هایی نبود که در آن نگهدارنده دستور می‌داد و من اجرا می‌کردم؛ بلکه لحظاتی از استدلال مشترک بود:«کلاس پایه مشترک ممکن است تکرار را کم کند، اما آیا کلاینت‌ها را به هم جفت می‌کند؟»«سازنده می‌تواند اینجا اعتبارسنجی کند، اما آیا این مسئولیت سازنده اصلی نیست؟»«نام پیش‌فرض بخش پیکربندی راحت است، اما وقتی کاربر به دو کلاینت چت نیاز دارد چه می‌شود؟»«کلاینت‌های بدیهی پوشش داده شده‌اند، اما وقتی توسعه‌دهنده به یک کلاینت کمتر رایج می‌رسد، SDK چه حسی خواهد داشت؟»این سؤالات پیاده‌سازی را بهتر کرد، اما مرا هم به مهندس بهتری تبدیل کرد.توصیه‌ای به توسعه‌دهندگانی که اولین مشارکت بزرگ خود را انجام می‌دهنداگر به یک مخزن کد بزرگ خیره شده‌اید و فکر می‌کنید آیا جای شما آنجاست یا نه، این چیزی است که اکنون به شما می‌گویم:۱. قبل از اینکه سندروم ایمپاستر ناپدید شود، شروع کنید. اعتمادبه‌نفس اغلب بعد از اقدام می‌آید، نه قبل از آن. کد را بخوانید، مشکل را محدود کنید، تست اضافه کنید و پیشنهادتان را بدهید.۲. اولین پیاده‌سازی خود را به عنوان «شروع یک گفتگو» ببینید. کد به نگهداران پروژه چیزی عینی برای ارزیابی می‌دهد. حتی اگر معماری تغییر کند، ارزش این کد از بین نمی‌رود.۳. بازخوردهای مربوط به طراحی را از قضاوت درباره خودتان جدا کنید. یک بررسی‌کننده سخت‌گیر ممکن است اساس رویکرد شما را به چالش بکشد. این به معنای به چالش کشیدن حق شما برای مشارکت نیست.۴. برای «راهکار ادغام شده» بهینه کنید، نه برای «حفظ کد اصلی خودتان». حذف یا بازنویسی کار خودتان شکست نیست؛ بلکه اغلب گواه این است که شما مشکل را عمیق‌تر از لحظه شروع درک کرده‌اید.۵. آیین‌های عملیاتی مخزن کد را یاد بگیرید. فرمت‌بندی، فایل‌های تولید شده، خطوط پایه API، قراردادهای تست و اسکریپت‌های CI بخشی از فرهنگ مهندسی پروژه هستند.۶. صبور باشید اما غیب نشوید. اگر طراحی متوقف شده است، روی گام بعدی توافق کنید، در دسترس بمانید و زمانی برگردید که پروژه شفافیت کافی برای پیشروی داشته باشد.۷. متوجه لحظه‌ای شوید که «همکاری» آغاز می‌شود. لحظه‌ای که یک نگهدارنده شروع به توضیح بده بستان‌ها (Trade-offs) می‌کند، جایگزین‌های عینی پیشنهاد می‌دهد یا در حل آخرین مشکل CI کمک می‌کند، شما دیگر صرفاً درخواست پذیرش نمی‌کنید؛ شما در حال ساختن چیزی به صورت مشترک هستید.تأمل نهاییPull Request من با یک ایده کاربردی شروع شد: پیکربندی و تزریق کلاینت‌های OpenAI در اپلیکیشن‌های .NET را آسان‌تر کنم و به چیزی بسیار ارزشمندتر ختم شد. یاد گرفتم که یک SDK بالغ چگونه طراحی API عمومی را ارزیابی می‌کند. یاد گرفتم چرا همسویی با اکوسیستم می‌تواند مهم‌تر از یک راهکار محلی ظریف باشد. یاد گرفتم که انتظار کشیدن می‌تواند یک تصمیم مهندسی باشد. یاد گرفتم که کامنت‌های بررسی (Review) اغلب درس‌های فشرده معماری هستند. یاد گرفتم که کامل بودن، تست‌ها، فایل‌های API تولید شده و CI همگی بخشی از «منتج کردن» (Shipping) هستند، نه کارهای اداری پیرامون آن و یاد گرفتم که متن‌باز صحنه‌ای نیست که در آن یک مشارکت‌کننده نبوغ فردی خود را ثابت کند. در بهترین حالت، متن‌باز جایی است که افرادی با زمینه‌های مختلف، به‌تدریج یک درک مشترک می‌سازند. مشارکت‌کننده انرژی، زمان و یک پیشنهاد عینی می‌آورد. نگهداران پروژه دانش تاریخی، محدودیت‌های اکوسیستم و مسئولیت آینده را می‌آورند. بررسی‌ها (Review)، این ورودی‌ها را به چیزی تبدیل می‌کند که هیچ‌کدام از طرفین به تنهایی نمی‌توانستند تولید کنند.نشان بنفش Merged رضایت‌بخش بود. البته که بود. اما پیروزی عمیق‌تر، درک این بود که من توانستم وارد کدبیسی شوم که در ابتدا مرا می‌ترساند، در میان عدم قطعیت و بازنگری‌ها بمانم، از افرادی که اکوسیستم را در عمق متفاوتی درک می‌کردند بیاموزم و کمک کنم تا یک ویژگی تا مراحل نهایی در پروژه جای بگیرد. اولین کامیت مهم بود چون سفر را آغاز کرد. ادغام (Merge) مهم بود چون من اصرار نکردم که سفر دقیقاً همان‌جایی تمام شود که در ابتدا تصور می‌کردم.</description><category>Amir Mokarchi</category><author>Amir Mokarchi</author><pubDate>Tue, 21 Jul 2026 08:24:53 +0330</pubDate></item><item><title>کانال‌های رویداد (Event Channels) در معماری مبتنی بر رویداد (EDA) چیست؟</title><link>https://virgool.ir/@mokarchi/کانال-های-رویداد-event-channels-در-معماری-مبتنی-بر-رویداد-eda-چیست-ldn85oxrbzby</link><description>کانال‌های رویداد مسیرهایی هستند که از طریق آن‌ها رویدادها بین  سرویس‌های مختلف منتقل می‌شوند. می‌توان این کانال‌ها را مشابه خطوط لوله  (Pipeline) یا صف‌های پیام (Queue) در نظر گرفت که وظیفه انتقال رویدادها  از یک سرویس تولیدکننده (Producer) به یک یا چند سرویس مصرف‌کننده  (Consumer) را بر عهده دارند.تعریف و نقش کانال‌های رویدادزمانی که یک Event Generator (مانند یک سرویس پرداخت یا ثبت سفارش) رویدادی را ایجاد می‌کند، این  رویداد باید از طریق یک کانال مناسب به مقصد برسد. این کانال می‌تواند به  صورت صف (Queue)، موضوع (Topic) یا جریان داده (Stream) پیاده‌سازی شود.اهمیت کانال‌های رویدادانتقال ناهمزمان (Asynchronous): رویدادها بدون نیاز به پاسخ فوری پردازش می‌شوند.انعطاف‌پذیری (Resilience): در صورت عدم دسترسی موقت یک سرویس، رویدادها در کانال باقی می‌مانند تا زمانی که سرویس مجدداً فعال شود.مقیاس‌پذیری (Scalability): امکان اتصال چندین سرویس به یک کانال و پردازش موازی رویدادها وجود دارد.اتصال سست (Loose Coupling): سرویس‌های تولیدکننده و مصرف‌کننده از یکدیگر مستقل هستند و وابستگی مستقیم ندارند.انواع کانال‌های رویداد1. صف (Queue)هر رویداد فقط توسط یک مصرف‌کننده پردازش می‌شود.مثال: صف OrderQueue برای پردازش سفارش‌ها.کاربرد: مناسب برای سناریوهایی که پردازش رویداد باید دقیقاً یک بار انجام شود (مانند پردازش پرداخت).2. موضوع (Topic)هر رویداد می‌تواند توسط چندین مصرف‌کننده دریافت شود.مثال: موضوع OrderPlacedTopic که هم توسط سرویس ارسال و هم سرویس فاکتورخوانی استفاده می‌شود.کاربرد: مناسب برای مواردی که چندین سرویس باید از یک رویداد مطلع شوند.3. جریان داده (Stream)رویدادها به صورت یک جریان پیوسته ذخیره و پردازش می‌شوند.مثال: PaymentStream که تاریخچه تراکنش‌ها را نگهداری می‌کند.کاربرد: مناسب برای پردازش بلادرنگ (Real-time) و تحلیل داده‌های حجیم.پیاده‌سازی در .NET (با RabbitMQ یا Kafka)1. تعریف صف برای پردازش سفارش‌هاpublic class OrderPlacedHandler&#xA;{&#xA;    private readonly IEventBus _eventBus;&#xA;&#xA;    public OrderPlacedHandler(IEventBus eventBus)&#xA;    {&#xA;        _eventBus = eventBus;&#xA;    }&#xA;&#xA;    public void HandleOrderPlaced(OrderPlacedEvent orderEvent)&#xA;    {&#xA;        Console.WriteLine($&#34;Processing order {orderEvent.OrderId}&#34;);&#xA;        _eventBus.PublishToQueue(&#34;OrderQueue&#34;, orderEvent);&#xA;    }&#xA;}2. تعریف موضوع برای اطلاع‌رسانی به چند سرویسpublic class OrderNotifier&#xA;{&#xA;    private readonly IEventBus _eventBus;&#xA;&#xA;    public OrderNotifier(IEventBus eventBus)&#xA;    {&#xA;        _eventBus = eventBus;&#xA;    }&#xA;&#xA;    public void NotifyServices(OrderPlacedEvent orderEvent)&#xA;    {&#xA;        _eventBus.PublishToTopic(&#34;OrderPlacedTopic&#34;, orderEvent);&#xA;    }&#xA;}نکات کلیدی در طراحی کانال‌های رویدادچند مصرف‌کننده (Multiple Consumers): در مدل Topic، چندین سرویس می‌توانند یک رویداد را دریافت کنند.صف مرده (Dead Letter Queue - DLQ): رویدادهای پردازش‌نشده به یک صف جداگانه منتقل می‌شوند تا بعداً بررسی شوند.حفظ ترتیب رویدادها (Event Ordering): در برخی سیستم‌ها مانند Kafka، ترتیب رویدادها حفظ می‌شود.کاربردهای واقعیپردازش پرداخت: ارسال رویداد PaymentProcessed به سرویس‌های حسابداری و انبارداری.مانیتورینگ: ارسال رویداد ErrorOccurred به سرویس‌های گزارش‌گیری.اینترنت اشیا (IoT): ارسال داده‌های سنسورها به یک جریان برای تحلیل بلادرنگ.چالش‌های اضافه بار در سیستم‌های مبتنی بر رویدادزمانی که حجم رویدادها از حد معمول فراتر رود، سیستم با مشکلات متعددی مواجه می‌شود:افزایش تأخیر در پردازش (Latency)انباشت پیام‌ها در صف‌ها (Queue Overflow)از کار افتادن مصرف‌کننده‌ها (Consumers Crash)از دست رفتن پیام‌ها (Message Loss)استراتژی‌های مدیریت اضافه بار۱. کنترل فشار پردازش (Backpressure Handling)مشکل: عدم توانایی مصرف‌کننده‌ها در پردازش رویدادها با سرعت مناسبراهکارها:محدودسازی نرخ تولید (Rate Limiting): کنترل تعداد رویدادهای تولید شده در واحد زمانکنترل جریان در Message Broker: تنظیم حداکثر پیام‌های در حال پردازشالگوی قطع ارتباط (Circuit Breaker): توقف موقت پردازش در صورت overloadمثال پیاده‌سازی در RabbitMQ:channel.BasicQos(prefetchSize: 0, prefetchCount: 10, global: false);۲. توازن بار بین مصرف‌کننده‌ها (Load Balancing)مشکل: توزیع ناعادلانه بار پردازش بین مصرف‌کننده‌هاراهکارها:افزایش افقی مصرف‌کننده‌ها (Horizontal Scaling)استفاده از Consumer Groups در Kafkaپیاده سازی Autoscaling در Kubernetesمثال پیاده‌سازی در Kafka:var config = new ConsumerConfig&#xA;{&#xA;    BootstrapServers = &#34;localhost:9092&#34;,&#xA;    GroupId = &#34;order-processing-group&#34;,&#xA;    EnableAutoCommit = false&#xA;};&#xA;&#xA;using var consumer = new ConsumerBuilder&lt;Ignore, string&gt;(config).Build();&#xA;consumer.Subscribe(&#34;order-events&#34;);&#xA;var consumeResult = consumer.Consume();&#xA;Console.WriteLine($&#34;Processing event: {consumeResult.Message.Value}&#34;);&#xA;consumer.Commit(consumeResult);۳. اولویت‌بندی پیام‌ها (Message Prioritization)مشکل: تأخیر در پردازش رویدادهای حیاتیراهکارها:پیاده‌سازی صف‌های با اولویتمسیریابی مبتنی بر موضوع برای رویدادهای مهممثال در RabbitMQ:var args = new Dictionary&lt;string, object&gt; { { &#34;x-max-priority&#34;, 10 } };&#xA;channel.QueueDeclare(&#34;priority-queue&#34;, true, false, false, args);۴. صف مرده (Dead Letter Queue - DLQ)مشکل: از دست رفتن پیام‌های پردازش نشدهراهکارها:انتقال پیام‌های ناموفق به صف جداگانهپیاده‌سازی سیاست‌های تکرار پردازشمثال در RabbitMQ:var args = new Dictionary&lt;string, object&gt;&#xA;{&#xA;    { &#34;x-dead-letter-exchange&#34;, &#34;dlx-exchange&#34; }&#xA;};&#xA;channel.QueueDeclare(&#34;order-queue&#34;, true, false, false, args);۵. پردازش دسته‌ای (Batch Processing)مشکل: ناکارآمدی در پردازش تک‌تک پیام‌هاراهکارها:پردازش گروهی پیام‌هااستفاده از Kafka Streamsمثال در Kafka:public void ProcessBatch(IEnumerable&lt;ConsumeResult&lt;Ignore, string&gt;&gt; messages)&#xA;{&#xA;    foreach (var message in messages)&#xA;    {&#xA;        Console.WriteLine($&#34;Processing batch message: {message.Value}&#34;);&#xA;    }&#xA;}۶. پردازش جریانی (Stream Processing)مشکل: چالش در پردازش بلادرنگ حجم بالای رویدادهاراهکارها:استفاده از Apache Flink یا Kafka Streamsتکنیک‌های پنجره‌بندی زمانیمثال در Kafka Streams:var builder = new StreamsBuilder();&#xA;var stream = builder.Stream&lt;string, string&gt;(&#34;payment-stream&#34;);&#xA;&#xA;stream.GroupByKey()&#xA;    .WindowedBy(TimeWindows.Of(TimeSpan.FromSeconds(5)))&#xA;    .Reduce((value1, value2) =&gt; value1 + value2);</description><category>Amir Mokarchi</category><author>Amir Mokarchi</author><pubDate>Wed, 02 Apr 2025 21:59:34 +0330</pubDate></item><item><title>تفاوت بین Event Choreography و Event Orchestration در EDA</title><link>https://virgool.ir/@mokarchi/تفاوت-بین-event-choreography-و-event-orchestration-در-eda-djpnwukjyn18</link><description>در معماری Event-Driven Architecture (EDA)، مدیریت جریان داده‌ها و هماهنگی بین سرویس‌های مختلف می‌تواند به دو روش Event Choreography و Event Orchestration انجام شود.در Event Choreography: سرویس‌ها به‌طور مستقل با هم تعامل دارند و هیچ کنترل‌کننده‌ی مرکزی وجود ندارد. در Event Orchestration: یک سرویس مرکزی (Orchestrator) مدیریت جریان داده‌ها و تعامل بین سرویس‌ها را برعهده دارد.سوال مهم:چه تفاوتی بین این دو روش وجود دارد؟کدام‌یک بهتر است؟ و در چه شرایطی باید از هر کدام استفاده کنیم؟رویکرد Event Choreography – هماهنگی غیرمتمرکز بین سرویس‌هادر Event Choreography، هر سرویس وقتی نیاز به انجام کاری دارد، یک Event منتشر می‌کند و سایر سرویس‌های مرتبط به این Event گوش می‌دهند و واکنش نشان می‌دهند.کنترل غیرمتمرکز: هیچ سرویس مرکزی وجود ندارد که فرایند را مدیریت کند. وابستگی کم(Loose Coupling): سرویس‌ها فقط Eventها را می‌شنوند و به آن‌ها پاسخ می‌دهند. مقیاس پذیری بالا: چون هیچ نقطه‌ی مرکزی کنترل‌کننده‌ای وجود ندارد، مقیاس‌پذیری بهتر است.مثال: پردازش سفارش در یک سیستم E-Commerceکلاس OrderService یک OrderPlaced Event منتشر می‌کند.کلاس PaymentService این Event را می‌شنود و پرداخت را پردازش کرده و یک PaymentProcessed Event منتشر می‌کند.کلاس InventoryService به OrderPlaced گوش می‌دهد و موجودی را کاهش می‌دهد.کلاس ShippingService به PaymentProcessed گوش می‌دهد و سفارش را ارسال می‌کند.در این روش، هیچ سرویس مرکزی مدیریت کل جریان را انجام نمی‌دهد، بلکه هر سرویس مستقل از دیگری واکنش نشان می‌دهد.مزایای Event Choreographyمقیاس‌پذیری بالا (Highly Scalable) توسعه و تغییر آسان (Flexible and Extensible) : اضافه کردن یک سرویس جدید فقط نیاز به گوش دادن به Eventهای موجود دارد. حداقل وابستگی بین سرویس‌ها (Loose Coupling)معایب Event Choreographyپیچیدگی بالا در مدیریت جریان داده‌ها : وقتی تعداد سرویس‌ها زیاد شود، ردگیری اینکه چه اتفاقی در سیستم رخ می‌دهد، دشوار می‌شود. دیباگ و مانیتورینگ سخت‌تر : چون هیچ کنترل‌کننده‌ای وجود ندارد، اشکال‌یابی بسیار پیچیده است.رویکرد Event Orchestration – هماهنگی متمرکز توسط یک Orchestratorدر Event Orchestration، یک سرویس مرکزی (Orchestrator) تعامل بین سرویس‌ها را مدیریت می‌کند.کنترل متمرکز: یک سرویس مرکزی مدیریت کل فرایند را بر عهده دارد. مدیریت وابستگی ها: Orchestrator تصمیم می‌گیرد که چه زمانی و چگونه هر سرویس باید فراخوانی شود. ردیابی و اشکال زدایی ساده‌تر: چون یک کنترل‌کننده‌ی مرکزی داریم، بررسی فرآیندها راحت‌تر است.مثال: پردازش سفارش در یک سیستم E-Commerce با استفاده از Orchestrationکلاس OrderService یک درخواست پردازش سفارش به OrderOrchestrator ارسال می‌کند.سپس OrderOrchestrator اول PaymentService را صدا می‌زند.بعد از تأیید پرداخت، OrderOrchestrator به InventoryService پیام می‌فرستد تا موجودی کالا را کاهش دهد.اگر موجودی کافی بود، OrderOrchestrator به ShippingService پیام می‌دهد تا سفارش را ارسال کند.در این روش، تمام تعاملات بین سرویس‌ها توسط یک Orchestrator کنترل و مدیریت می‌شوند.مزایای Event Orchestrationمدیریت و اشکال‌زدایی ساده‌تر (Easier Debugging &amp; Monitoring) هماهنگی بهتر بین سرویس‌ها (Better Coordination &amp; Dependencies Handling) کنترل بهینه بر ترتیب اجرای فرایندها (Explicit Execution Flow)معایب Event Orchestrationوابستگی بالا بین سرویس‌ها (Tight Coupling) : اگر Orchestrator خراب شود، کل سیستم ممکن است متوقف شود. مقیاس‌پذیری محدودتر نسبت به Choreography : تمام پردازش‌ها باید از طریق یک نقطه‌ی مرکزی انجام شوند.کدام‌یک بهتر است؟ Choreography یا Orchestration؟پاسخ: بستگی به سناریو دارد!بهتر است از Choreography استفاده کنیم اگر:تعداد زیادی سرویس کوچک داریم که مستقل از هم کار می‌کنند. می‌خواهیم مقیاس‌پذیری بالا داشته باشیم.اگر Eventها به طور طبیعی با هم تعامل دارند و نیازی به کنترل مرکزی نداریم. مثال: سیستم‌های مبتنی بر Microservices در یک پلتفرم Cloud-native.بهتر است از Orchestration استفاده کنیم اگر:فرآیندها به شدت به هم وابسته هستند و نیاز به هماهنگی دقیق دارند. نیاز به کنترل کامل روی اجرای فرآیندها داریم. مانیتورینگ و اشکال‌یابی فرآیندها مهم است. مثال: مدیریت فرآیندهای تجاری پیچیده (Business Process Management).روش ترکیبی: بهترین رویکرد؟در بسیاری از سیستم‌ها، ترکیب Choreography و Orchestration بهترین گزینه است.از Choreography برای تعاملات ساده و کم‌وابسته استفاده می‌کنیم.از Orchestration برای کنترل دقیق فرآیندهای حیاتی و وابسته بهره می‌بریم.مثال:کلاس OrderService یک Event OrderPlaced منتشر می‌کند.سپس Orchestrator به PaymentService و InventoryService پیام ارسال می‌کند.بعد از تأیید پرداخت و به‌روزرسانی موجودی، یک Event جدید منتشر می‌شود که سرویس‌های دیگر از طریق Choreography واکنش نشان می‌دهند.جمع‌بندیرویکرد Event Choreography: مناسب برای سیستم‌های توزیع‌شده‌ی مقیاس‌پذیر و منعطف که در آن سرویس‌ها مستقل هستند. رویکرد Event Orchestration: مناسب برای فرآیندهای پیچیده که به کنترل و مانیتورینگ دقیق نیاز دارند. رویکرد ترکیبی: استفاده‌ی هم‌زمان از هر دو روش برای مدیریت بهتر فرآیندها.</description><category>Amir Mokarchi</category><author>Amir Mokarchi</author><pubDate>Tue, 01 Apr 2025 10:53:07 +0330</pubDate></item><item><title>ملاحظات طراحی در Domain Model</title><link>https://virgool.ir/@mokarchi/ملاحظات-طراحی-در-domain-model-h0vgyjwfxf97</link><description>مدل، همیشه یک نمایش ساده‌شده از واقعیت است که بسته به هدفی که داریم، سطح جزئیاتش متفاوت می‌شود. مثلا یه ماکت ساختمان را در نظر بگیرید. این ماکت نشان میدهد که ساختمان چقدر فضا اشغال می‌کند، چند طبقه دارد، ولی نشان نمیدهد که سیم‌کشی داخلی یا سیستم تهویه چطور کار می‌کند.پس هر مدل، یک بخش خاص از واقعیت را نمایش میدهد و بقیه جزئیات رو حذف می‌کند، چون برای هدف فعلی ما مهم نیستند.مدل دامنه‌ای باید بخش‌هایی از دامنه را که برای حل مشکل مهم هستن نمایش بدهد. اضافه کردن اطلاعات اضافی باعث پیچیدگی بی‌مورد و افزایش هزینه‌ی توسعه می‌شود.مدل دامنه‌ای فقط باید به مسئله‌ای که قرار است حل شود مربوط باشد، نه چیزهای جانبی.چند تفاوت مهم بین مدل دامنه‌ای و مدل داده‌ای مدل دامنه‌ای (Domain Model)  بر روی رفتارها و قوانین کسب‌وکار تمرکز دارد در حالی که مدل داده‌ای (Data Model) بر روی ذخیره‌سازی داده‌ها تمرکز دارد.مدل دامنه‌ای (Domain Model) تعاملات بین مفاهیم و فرآیندها رو نمایش می‌دهد در حالی که مدل داده‌ای (Data Model) ارتباط بین جداول و فیلدهای دیتابیس را نمایش می‌دهد.مدل دامنه‌ای (Domain Model) برای ارتباط بین تیم‌ها استفاده می‌شود در حالی که مدل داده‌ای (Data Model) برای طراحی دیتابیس استفاده می‌شود.مدل دامنه‌ای (Domain Model) با EventStorming ساخته می‌شود اما مدل داده‌ای (Data Model) با ERD (Entity-Relationship Diagram) ساخته می‌شود.طراحی مدل دامنه‌ای یک فرآیند تکاملی است. ما نمی‌توانیم از ابتدا یک مدل بی‌نقص داشته باشیم، ولی یک سری اصول هست که به ما کمک میکنه:۱. از EventStorming برای کشف رویدادهای کلیدی استفاده کنیدقبل از هر چیز، باید Big Picture EventStorming رو اجرا کنیم تا درک بهتری از دامنه پیدا کنیم.سپس باید ، Design-Level EventStorming را انجام دهیم تا روی جزئیات بیشتر تمرکز کنیم.۲. مدل را ساده ولی دقیق طراحی کنیدمفاهیم پیچیده رو شکسته و به مدل‌های کوچک‌تر تقسیم کنید.از Ubiquitous Language استفاده کنید که همه افراد تیم متوجه مدل شوند.۳. مدل رو با استفاده از Aggregates، Entities و Value Objects بسازید۴. رفتارها و فرآیندها را در مدل نمایش بدهیدتمرکز فقط روی داده‌ها نباشد! باید مشخص کنیم که هر بخش از سیستم چطور عمل می‌کند و چه قوانینی دارد.۵. مدل را تست کنید و اصلاح کنیدبعد از طراحی اولیه، باید مدل را در عمل تست کنیم و مشکلاتش رو پیدا کنیم.مهم‌ترین چیز این است که مدل، نیازهای واقعی کسب‌وکار را پوشش دهد.چطور از EventStorming به طراحی مدل برسیم؟با استفاده از Big Picture EventStorming  میتوان فرآیندهای اصلی را پیدا کرد.رویدادهای دامنه‌ای(Domain Events) را تحلیل کنید تا رفتارها و قوانین مشخص شوند.موجودیت‌ها (Entities)، مقدارها(Value Objects) و Aggregates ر تعریف کنید.مدل را ابتدا روی کاغذ یا Whiteboard بررسی کنید و سپس در کد پیاده‌سازی کنید.تمرکز فقط روی داده‌ها نباشد، بلکه رفتارهای مهم دامنه‌ای را هم در مدل لحاظ کنید.</description><category>Amir Mokarchi</category><author>Amir Mokarchi</author><pubDate>Tue, 21 Jan 2025 20:33:48 +0330</pubDate></item><item><title>آشکارسازی مفاهیم پنهان در طراحی سیستم‌ها</title><link>https://virgool.ir/@mokarchi/آشکارسازی-مفاهیم-پنهان-در-طراحی-سیستم-ها-dtdyxbvjqwt9</link><description>وقتی سیستم ساخته می‌شود، مشکلاتی بوجود میاد که ظاهراً به خاطر سوءتفاهم‌های اولیه بوده است. این سوءتفاهم‌ها چطور ایجاد می‌شوند؟معمولاً این مشکلات به این خاطر به وجود میایند که چیزهایی که باید صریح و واضح باشند، مبهم یا ضمنی باقی میمانند. Implicit Concepts یا مفاهیم پنهان به زمانی گفته میشود که مفاهیم را شفاف نکنیم، که باعث برداشت های متفاوتی شود و همین باعث اختلاف یا اشتباه میگردد.مسأله: سوءتفاهم‌های ناشی از مفاهیم پنهانفرض کند در جلسه‌ای هستیم و درباره‌ی مشکلی حرف می‌زنیم. هرکسی تصویری در ذهنش از مشکل و راه‌حل دارد، ولی چون این تصاویر شفاف بیان نمی‌شوند، همه فکر می‌کنند با هم موافقند، در حالی که ممکن است کاملاً برداشت‌های متفاوتی داشته باشند.مثل وقتی که فکر می‌کنید منظور شخصی رو فهمیدید، ولی بعداً معلوم می‌شود اشتباه برداشت کردید؟این اتفاق معمولاً به خاطر سوگیری‌های شناختی مثل WYSIATI (What You See Is All There Is) رخ می‌دهد. ما براساس اطلاعات محدودی که داریم، تصمیم‌گیری می‌کنیم و فکر می‌کنیم کاملاً مشکل را فهمیدیم.مثال: فرم ثبت مرخصی پزشکییک فرم ساده ثبت مرخصی پزشکی رو در نظر بگیرید. فرض کند فرم اینگونه طراحی شده:یک فیلد برای Start Dateیک فیلد برای End Dateیک چک‌باکس برای Half Dayو یک دکمه برای Saveدر نگاه اول، این فرم ممکن است ساده به نظر برسد. ولی وقتی دقت کنید، کلی ابهام دارد:فیلد Start Date: این تاریخ یعنی چه زمانی؟ روزی که مرخصی ثبت شده یا روزی که کارمند سر کار نیامده است؟فیلد End Date: این یعنی آخرین روز مرخصی؟ یا روزی که کارمند برگشته است سر کار؟فیلد Half Day: آیا به شروع مرخصی اشاره دارد یا به پایان اش؟فیلد Save: وقتی کاربر روی این دکمه کلیک می‌کند، چه اتفاقی می‌افتد؟ آیا فقط داده ذخیره می‌شود یا فرآیند تأیید مرخصی هم شروع می‌شود؟این فرم خیلی گنگ است. حالا یک فرم مشابه رو در نظر بگیر که فیلدها و دکمه‌هاش شفاف‌تر تعریف شده اند:فیلد First Day Not At Work (اولین روزی که کارمند سر کار نیامده است)فیلد Came Back To Work (روزی که کارمند برگشته است)فیلد Left During Workday (آیا مرخصی از وسط روز شروع شده است؟)و یک دکمه مثل Submit for Approval (ارسال برای تأیید).این فرم مشخص و واضح طراحی شده است.</description><category>Amir Mokarchi</category><author>Amir Mokarchi</author><pubDate>Tue, 21 Jan 2025 08:52:31 +0330</pubDate></item><item><title>دانش دامنه</title><link>https://virgool.ir/@mokarchi/دانش-دامنه-ude8ob26t1ob</link><description>دانش دامنه یا Domain Knowledge به دانش مرتبط با حوزه‌ای که نرم‌افزار در اون کار می‌کنه اشاره میکنه. مثلاً اگه دارید یک سیستم معاملات مالی طراحی می‌کنید، باید درباره معاملات مالی اطلاعات داشته باشید. بدون این دانش، نمی‌توانید به درستی مشکلات کاربران را درک کنید یا حتی زبانشان را بفهمید.اما، مگر نمی‌شود از مشخصات یا اسناد فنی استفاده کرد؟ چرا باید درباره دامنه چیزی بدانیم؟مشخصات و اسناد فقط بخشی از اطلاعات را بیان میکنند. ولی اگر دانش دامنه نداشته باشید:نمی‌توانید به درستی با کاربران صحبت کنید، چون اصطلاحاتشان رو نمی‌فهمید.اعتماد بین شما و مشتری سخت‌تر شکل می‌گیرد.ممکن است فقط همان چیزی را که در سند نوشته شده است، بسازید، ولی راه‌حل واقعی که مشکل را حل می‌کند، را پیدا نکنید.وقتی دانش دامنه داشته باشید، مکالمه با کاربران مفیدتر می‌شود. در نهایت وقتی شما به زبانشان صحبت می‌کنید و مشکلاتشان را می‌فهمید، بیشتر به شما اعتماد می‌کنند.چطور دانش دامنه به دست بیاریم؟با همکاری مؤثر می‌توانیم دانش لازم را کسب کنیم. چند روش اصلی برای به دست آوردن دانش دامنه وجود دارد:مکالمات (Conversations):رایج‌ترین روش است. در جلسات یا گفتگوهای رسمی و غیررسمی از کاربران سوال بپرسد. باید خوب گوش بدهید و سوال‌های دقیق بپرسید تا اطلاعات مفید بگیرید.مشاهده (Observation):این روش خیلی قدرتمند است. باید از پشت میز بلند شوید و ببینید کاربران چطور کار می‌کنند. مثلاً به انبار، هتل یا دفتر معاملات سر بزنید. به کارهایی که انجام می‌دهند دقت کنید. Jeff Patton در یکی از سخنرانی‌هاش مثال‌های خوبی در این مورد دارد.داستان‌سرایی دامنه (Domain Storytelling):این روش توسط Stefan Hofer و همکارانش معرفی شده است. از تصاویر ساده، فلش‌ها و کمی متن برای توضیح تعاملات درون دامنه استفاده می‌کند. این روش آسان و نیاز به توضیحات پیچیده ندارد.و EventStorming:این روش توسط Alberto Brandolini ابداع شده است و از Post-it Notes و یک رول کاغذ استفاده می‌کند. در کارگاه‌های EventStorming، شرکت‌کننده‌ها اتفاقات گذشته (Events) را روی یادداشت‌های چسبان می‌نویسند و در روی دیوار به ترتیب زمانی می‌چسبانند. این روش به کشف فرآیندها، فعالیت‌ها و حتی ابهامات کمک می‌کند.چالش‌های یادگیری دانش دامنهافراد در دامنه خودشان سال‌ها کار می‌کنند و متخصص می‌شوند. یادگیری این دانش برای ما که توسعه‌دهنده‌ هستیم، زمان‌بر است. به‌علاوه:گاهی دانش در سازمان پراکنده‌ است.ممکن است بعضی افراد اطلاعات اشتباه داشته باشند یا بخشی از دانش شان نادیده گرفته شده باشد.چطور دانش دامنه خوب را تشخیص بدیم؟باید با افراد مختلف از بخش‌های مختلف سازمان صحبت کنیم. از مدیران تا کارمندهای سطح پایین‌تر گرفته. هر کسی یک بخش از پازل را دارد. وظیفه ما این است که این تکه‌ها را کنار هم بگذاریم.</description><category>Amir Mokarchi</category><author>Amir Mokarchi</author><pubDate>Sun, 19 Jan 2025 23:42:11 +0330</pubDate></item><item><title>تصمیم‌گیری و سوگیری‌های شناختی</title><link>https://virgool.ir/@mokarchi/تصمیم-گیری-و-سوگیری-های-شناختی-klclhkpjxuoi</link><description>ما چطور تصمیم می‌گیریم و چرا گاهی تصمیمات اشتباه می‌گیریم؟ انگار یه چیزی تو مغزمون باعث میشه منطقی عمل نکنیم.مغز ما همیشه در حال پردازش اطلاعاته و برای اینکه این حجم از اطلاعات رو مدیریت کنه، دو نوع فرآیند داره:فرآیند خودکار (Implicit/Automatic Process)، که ناخودآگاه و سریع انجام می‌شه.فرآیند آگاهانه (Explicit/Conscious Process)، که آهسته‌تر و نیاز به تلاش و انرژی بیشتری داره.این تقسیم‌بندی به اسم Dual Process Theory شناخته می‌شه و توسط Keith Stanovich و Richard West به عنوان System 1 و System 2 معرفی شده.دو سیستم تصمیم‌گیری مغز System 1 و System 2: در System 1: سریع، خودکار و مبتنی بر تجربه‌های گذشته است. مثل رانندگی وقتی دیگه مهارت پیدا کردی.در System 2: آهسته، منطقی و نیازمند تلاش فکریه. مثل وقتی که داری یه مسأله پیچیده ریاضی حل می‌کنی.دنیل کانمن توی کتاب معروفش Thinking, Fast and Slow این سیستم‌ها رو توضیح داده. System 1 معمولاً سوگیری‌های شناختی (Cognitive Biases) ایجاد می‌کنه، چون به جای تحلیل، به تجربیات گذشته و احساسات تکیه می‌کنه.سوگیری‌های شناختی و تأثیر آن‌ها در تصمیم‌گیریسوگیری‌ها افکار و تمایلات ناخودآگاه هستن که روی قضاوت‌ها و تصمیمات ما تأثیر می‌ذارن. چند مثال از این سوگیری‌ها در طراحی سیستم‌ها:سوگیری تأیید انتخاب Choice-Supportive Bias :وقتی یه چیزی رو انتخاب می‌کنی، حتی اگه نقص داشته باشه، بهش پایبند می‌مونی. مثلاً وقتی یه فریم‌ورک انتخاب کردی، ممکنه حتی اگه بهترهاش وجود داشته باشه، همچنان ازش استفاده کنی.سوگیری تأیید Confirmation Bias :فقط دلایلی که انتخابت رو تأیید می‌کنن می‌شنوی و بقیه رو نادیده می‌گیری.اثر همراهی با جمع Bandwagon Effect :وقتی اکثریت با چیزی موافق باشن، ناخودآگاه فکر می‌کنی اونا درست می‌گن، حتی اگه دلیل منطقی وجود نداشته باشه.اعتماد به نفس بیش از حد Overconfidence :معمولاً افراد در توانایی‌هاشون بیش از حد خوش‌بین هستن. مثلاً زمان لازم برای انجام یه پروژه رو کمتر از واقعیت تخمین می‌زنن.هیوریستیک در دسترس Availability Heuristic :فقط به اطلاعاتی که در دسترس داری تکیه می‌کنی و نمی‌ری اطلاعات بیشتری جمع کنی. این باعث می‌شه پیچیدگی مسأله رو دست‌کم بگیری.وقتی از Domain-Driven Design (DDD) استفاده می‌کنیم، باید تصمیم‌های دقیقی بگیریم. برای این کار، باید از System 2 بیشتر استفاده کنیم و جلوی System 1 و سوگیری‌هاش رو بگیریم. مثلاً وقتی قراره یک مسأله پیچیده رو دسته‌بندی کنیم (مثل چارچوب Cynefin)، ممکنه System 1 سریع تصمیم بگیره و مسأله رو ساده‌تر از واقعیت دسته‌بندی کنه. این باعث می‌شه راه‌حل اشتباهی انتخاب کنیم.چطور سوگیری‌ها رو مدیریت کنیم؟آگاه باش: همیشه بدون که سوگیری‌ها وجود دارن.فعال  کردن System 2 : قبل از تصمیم‌گیری، فکر کن و اطلاعات بیشتری جمع کن.نظر دیگران رو بپرس: چون ممکنه دیگران زاویه‌های مختلفی رو ببینن که تو نمی‌بینی.از روش‌های طراحی مشارکتی استفاده کن: مثل EventStorming که توش همه ذینفعان درگیر می‌شن و می‌تونن دیدگاه‌های خودشون رو ارائه بدن.آموزش ببین</description><category>Amir Mokarchi</category><author>Amir Mokarchi</author><pubDate>Sun, 19 Jan 2025 08:55:46 +0330</pubDate></item><item><title>پیچیدگی ذاتی و پیچیدگی تصادفی</title><link>https://virgool.ir/@mokarchi/پیچیدگی-ذاتی-و-پیچیدگی-تصادفی-gylsxer6y7x1</link><description>دو مفهوم &#34;Essential Complexity&#34; و &#34;Accidental Complexity&#34; اولین بار توسط فرد بروکس (Fred Brooks)، برنده جایزه تورینگ، در مقاله معروفش No Silver Bullet در سال ۱۹۸۶ مطرح شد. بروکس دو نوع پیچیدگی رو تعریف کرد:پیچیدگی ذاتی Essential Complexity که از خود دامنه مسأله و مشکل نشأت گرفته میشه و بدون کاهش محدوده مسأله حذف شدنی نیست.پیچیدگی تصادفی Accidental Complexity که توسط خود راه‌حل ایجاد میشه، مثل استفاده از یک فریم‌ورک (Framework)، پایگاه داده، یا زیرساخت‌های دیگر...بروکس معتقد بود که با رشد صنعت نرم‌افزار، پیچیدگی تصادفی کم شده است. ابزارهای پیشرفته و زبان‌های برنامه‌نویسی سطح بالا به توسعه‌دهنده‌ها زمان بیشتری برای کار روی مسائل کسب‌وکار میدهند. ولی با این وجود بعد از ۳۰ سال، هنوز با پیچیدگی تصادفی درگیر هستیم.مثلاً کانتینرها (Containers) رو در نظر بگیرید که قرار بود میزبانی از اپلیکیشن‌ها ما رو راحت کنه. ولی بعدتر نیاز به ارکستریتور (Orchestrator) داشتیم و کار به Kubernetes رسید. و حالا بیشتر زمان خودمون رو صرف نوشتن فایل‌های YAML میکنیم تا کدنویسی واقعی.پیچیدگی ذاتی مستقیماً به فضای مشکل مربوط میشه، چون از خود مشکل ناشی میشه. ولی پیچیدگی تصادفی بیشتر به فضای راه‌حل مرتبط هست، چون از ابزارها و روش‌هایی که برای حل مشکل استفاده می‌کنیم، میاد.بیاید برای نمونه یک مثال واقعی رو بررسی کنیم: یک گزارش که قبلاً ماهانه تولید میشد، حالا باید به صورت بلادرنگ (Real-Time) اجرا بشه. بعد از چند ماه تیم توسعه، تخمین زد که تکمیل این قابلیت حداقل ۶ ماه دیگه زمان میبره و ۱ میلیون پوند هزینه داره. دلیلش هم این بود که دیتابیس تراکنشی (Transactional Database) بهینه نبود و باید از روش‌هایی مثل شاردینگ (Sharding)، توزیع جغرافیایی (Geographical Distribution)، و تکرار داده‌ها (Replication) استفاده میشد.وقتی نیاز واقعی مشتری رو تحلیل کردن، فهمیدن که مشتری فقط می‌خواست همون گزارش ماهانه رو هفتگی اجرا کنه. با یه تغییر ساده در زمان‌بندی، مشکل حل شد و نیازی به طراحی مجدد کل سیستم نبود.خیلی وقت‌ها ما توسعه‌دهنده‌ها عاشق اصولی مثل DRY هستیم و به دنبال انتزاع‌هایی هستیم که کدمون رو شیک‌تر کنه. ولی گاهی این انتزاع‌ها کاملاً غیرضروریه. این همون چیزی هست که بهش میگن Over-Engineeringپس قانون کلی اینه که پیچیدگی ذاتی رو بپذیریم و پیچیدگی تصادفی رو کم کنیم، و معمولاً این پیچیدگی تصادفی به خاطر مهندسی بیش از حد (Over-Engineering) به وجود میاد.دسته‌بندی پیچیدگی‌ها کمک می‌کنه قبل از حل مسأله بفهمیم که با چه سطحی از پیچیدگی روبرو هستیم. یک چارچوب خیلی معروف برای این کار هست به اسم Cynefin که توسط Dave Snowden و Mary Boone در یک مقاله در سال ۲۰۰۷ معرفی شد. ابزارهایی مثل DDD، EventStorming و Event Sourcing به ما کمک می‌کنن پیچیدگی‌های رو بهتر مدیریت کنیم.</description><category>Amir Mokarchi</category><author>Amir Mokarchi</author><pubDate>Sat, 18 Jan 2025 16:12:32 +0330</pubDate></item><item><title>چالش‌ها و راهکارهای تعیین نیازمندی‌های نرم‌افزار</title><link>https://virgool.ir/@mokarchi/چالش-ها-و-راهکارهای-تعیین-نیازمندی-های-نرم-افزار-janfv7daxxhn</link><description>یکی از حساس‌ترین و مهم‌ترین مراحل در توسعه‌ی هر نرم‌افزار، مشخص کردن نیازمندی‌ها (Requirements) است. کیفیت و شفافیت نیازمندی‌ها تأثیر مستقیمی بر موفقیت پروژه دارد؛ اما متأسفانه، اغلب در این مرحله با مشکلاتی مواجه می‌شویم. مشکل کجاست؟1. فاصله بین مشتری و توسعه‌دهندهدر فرآیندهای سنتی، توسعه‌دهندگان معمولاً به‌صورت مستقیم با کسانی که مشکل واقعی را تجربه می‌کنند، در ارتباط نیستند.نقش تحلیل‌گران: افرادی مانند تحلیل‌گران نیازمندی، تحلیل‌گران کسب‌وکار یا مدیران محصول، میانجی بین تیم توسعه و مشتری هستند.ریسک انتقال ناقص اطلاعات: وقتی دیدگاه و تفسیر تحلیل‌گر وارد اسناد نیازمندی می‌شود، ممکن است بخش مهمی از مشکل یا انتظارات واقعی کاربر نادیده گرفته شود یا به اشتباه فهمیده شود.2. توصیف راه‌حل به‌جای مشکلدر اغلب اسناد نیازمندی‌ها، راه‌حل توصیف می‌شود نه خود مشکل.مثال: جمله‌ای مثل «هر روز، سیستم باید لیستی از مهمانان هتل که قرار است وارد یا خارج شوند را تولید کند» تنها راه‌حل را توصیف می‌کند، نه این‌که مشکل اصلی چیست.خطر تمرکز بر راه‌حل: وقتی تنها راه‌حل مطرح باشد، احتمال این‌که راه‌حل‌های بهتر و مؤثرتر را از دست بدهیم، زیاد می‌شود.3. حتی داستان‌های کاربری (User Stories) هم ممکن است راه‌حل نباشندروش‌های چابک (Agile) معمولاً از User Story برای بیان نیازمندی‌ها استفاده می‌کنند. این داستان‌ها تا حدی بهتر عمل می‌کنند، اما همچنان گاهی مشکل اصلی را پنهان می‌کنند.مثال: در جمله «به‌عنوان مدیر انبار، من نیاز دارم گزارش سطح موجودی را چاپ کنم تا بتوانم به‌موقع سفارش بدهم»، مشکل ریشه‌ای می‌تواند خیلی عمیق‌تر باشد: شاید سیستم خرید نیاز به اتوماسیون و پیش‌بینی داشته باشد تا دیگر نیازی به گزارش دستی نباشد.راهکارها برای حل مشکلات نیازمندی‌ها1. ارتباط مستقیم تیم توسعه با کاربران نهاییدر روش‌های Lean و Agile بر اهمیت ارتباط مستقیم بین تیم توسعه و کاربران نهایی تأکید می‌شود.مزیت: وقتی تیم توسعه مشکل را از زبان کاربر بشنود، هم شناخت بهتری از ابعاد مسئله پیدا می‌کند، هم احتمال سوءتفاهم کاهش می‌یابد.2. استفاده از پروتوتایپ (Prototype)ساخت نمونه‌ی اولیه و گرفتن بازخورد از کاربران نهایی، می‌تواند به شناسایی نیازهای واقعی و حذف فرضیات نادرست کمک کند.چرخه‌ی سریع: در هر تکرار (Iteration) یک پروتوتایپ تولید و تست می‌شود و بازخوردها به‌سرعت به تیم توسعه منتقل می‌گردند.3. رویکردهای طراحی دامنه‌محور (DDD)در Domain-Driven Design (DDD) توصیه میشود تیم‌ها با درک عمیق از دامنه‌ی کاری مشتری (Domain)، به راهکارهای نرم‌افزاری دست یابند.مزیت: با درک دقیق مدل کسب‌وکار، نیازمندی‌ها به‌صورت شفاف‌تری بیان می‌شوند و درک مشترک بین تیم‌های فنی و کسب‌وکار شکل می‌گیرد.4. تمرکز بر «مشکل» پیش از «راه‌حل»به‌جای این‌که بپرسید «چه چیزی باید بسازیم؟»، بهتر است ابتدا پرسیده شود «چه مشکلی باید حل شود؟» یا «چه نیازی باید برطرف شود؟».مزیت: تعریف دقیق مشکل، راه را برای یافتن راه‌حل خلاقانه باز می‌کند و گزینه‌های بیشتری را پیش روی تیم توسعه می‌گذارد.نتیجه‌گیریاگرچه تدوین نیازمندی‌های نرم‌افزار اغلب مشکل‌ساز و گیج‌کننده است، اما با تمرکز بر فهم مشکل به‌جای تمرکز صرف بر راه‌حل، استفاده از متدولوژی‌های چابک و Lean، به‌کارگیری پروتوتایپ‌ها و بهره‌گیری از رویکردهایی همچون Domain-Driven Design، می‌توان کیفیت نیازمندی‌ها را به‌شدت ارتقا داد. در نهایت، هر چه تیم توسعه و ذی‌نفعان پروژه با هم ارتباط بیشتری داشته باشند و مشکل واقعی کاربر را بهتر درک کنند، احتمال موفقیت محصول نرم‌افزاری بالاتر می‌رود.</description><category>Amir Mokarchi</category><author>Amir Mokarchi</author><pubDate>Sat, 18 Jan 2025 13:04:10 +0330</pubDate></item><item><title>درباره Problem Space و Solution Space</title><link>https://virgool.ir/@mokarchi/درباره-problem-space-و-solution-space-kmtyfkhhwmhg</link><description>این دو نظریه‌ که توسط &#34;Allen Newell&#34; و &#34;Herbert Simon&#34; در کتاب Human Problem Solving مطرح شده است. اساساً، بیان میکند که ما آدم‌ها برای حل مسائل، در یک فضای خاص به نام &#34;Problem Space&#34; به دنبال راه‌حل می‌گردیم.در &#34;Problem Space&#34; حالت اولیه (Initial State) و حالت مطلوب یا نهایی (Desired State) یک مسأله را تعریف میکنیم. همچنین حالت‌های میانی (Intermediate States)، محدودیت‌ها (Constraints) از جمله قوانینی است که به نوعی زمینه مسأله رو مشخص می‌کند.در صنعت نرم‌افزار، افرادی که بیشتر در &#34;Problem Space&#34; فعالیت می‌کنند، معمولاً مشتری‌ها (Customers) و کاربران (Users) هستند. &#34;Solution Space&#34; اساساً همان مسیری است که از وضعیت اولیه تا وضعیت نهایی و همه جزئیات مربوط به راه‌حل را شامل میشود. هر مسأله واقعی نیاز به راه‌حل دارد، و اگر درست درProblem Space جستجو کنیم، می‌توانیم بفهمیم که چه گام‌هایی باید برداریم. نمونه زیر مثال روشنی از این موضوع است.داستان کلاسیک نوشتن در فضا. در دهه ۱۹۶۰ کشورهایی که دنبال اکتشافات فضایی بودند فهمیدند که خودکار معمولی در فضا کار نمی‌کند چون جاذبه وجود ندارد. ظاهراً ناسا یک میلیون دلار خرج کرد تا خودکاری طراحی کند که در فضا کار کند، اما شوروی‌ها از مداد استفاده کردند که تقریباً هیچ هزینه ای نداشت.اما واقعیت ماجرا چیست!!!این داستان یک افسانه‌ست. ناسا هم مداد رو امتحان کرد ولی به خاطر مشکلاتی مثل تولید گرد و غبار ریز (Microdust)، شکستن نوک‌ها و قابلیت اشتعال چوب مداد، کنار گذاشته شد. در نهایت، یک شرکت خصوصی به اسم &#34;Fisher&#34; خودکاری به نام &#34;Space Pen&#34; طراحی کرد که بعد از آزمایش، هم ناسا و هم شوروی از آن استفاده کردند. قیمت برای هر خودکار هم فقط ۲.۳۹ دلار بود.پس مشکل از مداد بود؟ مشکل پیچیده‌تر از چیزی بود که در نگاه اول به نظر می‌رسید. اینجا محدودیت‌های اضافی یا به اصطلاح نیازمندی‌های غیرعملکردی (Non-Functional Requirements) و دقیق‌تر بیان کنم، نیازمندی‌های عملیاتی (Operational Requirements)، کار راسخت‌تر کرده بود.وقتی سریع به راه‌حل فکر می‌کنی، مغز دیگر روی خود مشکل متمرکز نمی‌شود. مثلاً &#34;Bart Barthelemy&#34; و &#34;Candace Dalmagne-Rouge&#34; در مقاله‌ای که در مجله Harvard Business Review منتشر شد بیان میکنند که وقتی به نوآوری فکر می‌کنید، باید از اینکه سریع دنبال راه‌حل بروید، خودداری کنید.چون، وقتی به اولین راه‌حلی که به ذهن می‌رسه فکر می‌کنید، شروع می‌کنید به گسترش جزئیات همون راه‌حل و به جای حل مسأله، روی ایده‌ای که به نظرت خوبه کار می‌کنید. ممکنه این ایده اصلاً بهترین راه‌حل نباشه.رویکرد Exploratory Approachدر این رویکرد، همیشه باید به دنبال ایده‌های دیگر هم بگردیم به جای اینکه فقط ایده اولیه رو بهتر کنیم باید چندین گزینه دیگر رو نیز آزمایش کنیم. این ممکنه سخت‌تر باشه ولی معمولاً جواب دقیق‌تر و ارزشمندتری میده.</description><category>Amir Mokarchi</category><author>Amir Mokarchi</author><pubDate>Fri, 17 Jan 2025 20:08:41 +0330</pubDate></item><item><title>چارچوب Cynefin</title><link>https://virgool.ir/@mokarchi/چارچوب-cynefin-v0szp1gf5siw</link><description>یک چارچوب شناختی (Sensemaking Framework) است که توسط دیو اسنودن (Dave Snowden) و مری بون (Mary Boone) در سال ۲۰۰۷ معرفی شد، ابزاری است برای کمک به رهبران و تصمیم‌گیران تا بتوانند با درک ماهیت موقعیت‌ها، رویکرد و شیوه‌ی واکنش بهتری انتخاب کنند. این چارچوب فقط مختص مدیریت کلان یا تصمیم‌گیری راهبردی نیست؛ می‌توان آن را در حوزه‌های مختلف از جمله توسعه نرم‌افزار نیز به‌خوبی به کار گرفت. ایده‌ی اصلی این است که هنگام تصمیم‌گیری در مورد نحوه‌ی طراحی، پیاده‌سازی، تست، دیباگ یا حتی مدیریت تیم و فرایندهای توسعه، ابتدا تشخیص دهید که با چه نوع مسئله‌ای روبه‌رو هستید و بعد متناسب با همان فضا عمل کنید. این چارچوب پنج حوزه (Domain) اصلی دارد که هر کدام نوع خاصی از پیچیدگی و عدم‌قطعیت را نشان می‌دهند:۱. حوزه‌ی ساده (Obvious/Simple)مشخصه: رابطه‌ی علی و معلولی روشن است و روش‌های راه‌حل از پیش مشخص و اثبات‌شده‌اند.رویکرد پیشنهادی: «حس کردن - دسته‌بندی کردن - پاسخ دادن» (Sense – Categorize – Respond)مثال کاربردی: فرض کنید شما مسئول موجودی انبار یک سوپرمارکت کوچک هستید. روش‌های استانداردی برای سفارش مجدد کالا وجود دارد (مثلاً وقتی کالایی به زیر یک حد خاص رسید سفارش جدید دهید). مسئله روشن است، راه‌حل‌ها مشخص هستند، و خطای زیادی هم ممکن است رخ ندهد. کافی است دستورالعمل‌های مشخص را دنبال کنید.چالش بالقوه در این حوزه این است که مدیر یا مسئول ممکن است دچار اعتماد به نفس کاذب شود و شرایط را بیش از حد ساده ببیند. در این صورت، ممکن است زمانی‌که اوضاع پیچیده یا پیچیده‌تر می‌شود، غافلگیر شود.۲. حوزه‌ی پیچیده (Complicated)مشخصه: رابطه‌ی علت و معلولی وجود دارد، اما برای تشخیص و استفاده از راه‌حل باید از کارشناسان و تخصص‌های مختلف کمک گرفت. پاسخ‌های صحیح متنوع هستند، اما می‌توان با تحلیل و دانش تخصصی به جواب رسید.رویکرد پیشنهادی: «حس کردن - تحلیل کردن - پاسخ دادن» (Sense – Analyze – Respond)مثال کاربردی: فرض کنید می‌خواهید یک کمپین بازاریابی در فضای آنلاین اجرا کنید. شما برای بخش‌های مختلف (سئو، تبلیغات کلیکی، شبکه‌های اجتماعی و ...) احتمالاً از متخصصان کمک می‌گیرید. همه چیز مبهم نیست، اما تحلیل و دانش عمیق در بخش‌های مختلف لازم است تا نتیجه‌ی مطلوب حاصل شود.مسئله‌ی کلیدی: روش پاسخ در حوزه‌ی پیچیده این است که ابتدا حس کنید و اطلاعات جمع کنید، سپس با تحلیل تخصصی به راهکار دست یابید. مدیران در این حوزه باید به کارشناسان اعتماد کنند.۳. حوزه‌ی پیچیده (Complex)مشخصه: روابط علت و معلولی به‌صورت شفاف قابل شناسایی نیستند و از قبل نمی‌دانید کدام راه‌حل حتماً موفقیت‌آمیز خواهد بود. بهترین رویکرد، آزمایش و تست روش‌های مختلف، مشاهده‌ی نتایج و سپس انطباق با شرایط است.رویکرد پیشنهادی: «پروب کردن - حس کردن - پاسخ دادن» (Probe – Sense – Respond)مثال کاربردی: شما یک استارتاپ دارید که راه‌حل نوآورانه‌ای ارائه می‌دهد و بازار هدف هم جدید است. دقیقاً نمی‌دانید کدام استراتژی فروش، جذب سرمایه یا توسعه‌ی محصول بهترین نتیجه را خواهد داشت. در این شرایط، ابتدا چند آزمایش کوچک (پایلوت) انجام می‌دهید تا رفتار مشتریان را بسنجید، سپس با مشاهده‌ی نتایج، مسیرتان را اصلاح می‌کنید.نکته‌ی مهم: در حوزه‌ی پیچیده «پروب کردن» (ساختن آزمایش‌های کنترل‌شده) و جمع‌آوری بازخورد، کلید موفقیت است.۴. حوزه‌ی آشوبناک (Chaotic)مشخصه: هیچ رابطه‌ی علی و معلولی مشخص نیست و یا اگر باشد آن‌قدر شرایط بی‌ثبات و بحرانی است که فرصتِ تحلیل دقیق وجود ندارد. اولین کار، ایجاد ثبات اولیه و جلوگیری از گسترش بحران است.رویکرد پیشنهادی: «اقدام کردن - حس کردن - پاسخ دادن» (Act – Sense – Respond)مثال کاربردی: در دقایق اولیه بعد از یک فاجعه طبیعی، مهم‌ترین کار نجات جان افراد و تأمین نیازهای فوری است. برنامه‌ریزی‌های بلندمدت یا تحلیل‌های پیچیده بعداً انجام می‌شود. اول باید عمل کنید تا بحران را از حادترین حالت بیرون بیاورید.فلسفه‌ی اقدام: «اول عمل کن تا جلوی فاجعه را بگیری، بعد ببین اوضاع چطور است، سپس تصمیم‌های بعدی را بگیر.»۵. حوزه‌ی نابه‌سامانی (Disorder)مشخصه: در این حوزه مشخص نیست که وضعیت ما جزو کدام یک از چهار حوزه‌ی قبلی است. ممکن است بخشی از سیستم ساده باشد، قسمتی پیچیده باشد و بخشی هم کاملاً آشفته باشد. در این حالت بهترین رویکرد، «تقسیم وضعیت به بخش‌های قابل فهم» است تا بتوان آن‌ها را در حوزه‌ی مناسب خود قرار داد.مثال کاربردی: گاهی آن‌قدر ابعاد پروژه وسیع است که نمی‌توان به‌سرعت تشخیص داد کدام بخش روتین و ساده است، کدام بخش نیازمند تخصص بیشتر است، کدام بخش پیچیده (Complex) و کدام بخش در آشوب به‌سر می‌برد. در این حالت باید پروژه را خرد کرد و اجزای آن را در حوزه‌های مناسب قرار داد و بر اساس آن‌ها تصمیم‌گیری کرد.نکات تکمیلی و توصیه‌های عملیجابه‌جایی حوزه‌ها: ممکن است وضعیت از یک حوزه به حوزه‌ی دیگر تغییر کند. برای مثال، اگر بحران مدیریت نشود، حوزه‌ی پیچیده (Complex) می‌تواند به آشوب (Chaotic) تبدیل شود. یا ممکن است بعد از یک دوره‌ی طولانی نوآوری در حوزه‌ی پیچیده، در نهایت به یک دستورالعمل تثبیت‌شده برسیم که آن را به حوزه‌ی ساده منتقل کند.هم‌پوشانی حوزه‌ها: گاهی در یک پروژه‌ی بزرگ، بخش‌هایی از آن ساده و روتین هستند (مثلاً کارهای تکراری اداری)، ولی بخش‌هایی دیگر Complex یا حتی Chaotic هستند (مثلاً درگیرشدن با یک بحران تأمین کالا). مدیران باید بخش‌ها را تفکیک کنند و برای هر بخش روش تصمیم‌گیری مناسبی اتخاذ کنند.اهمیت فرهنگ سازمانی: در حوزه‌ی پیچیده، نیاز به فرهنگ «یادگیری مداوم» و «آزمایش سریع و ارزان» (Fail Fast) پررنگ است. سازمان‌هایی که اشتباه را تاب نمی‌آورند، در این حوزه مشکل خواهند داشت، زیرا از ترس شکست دست به هیچ آزمایشی نمی‌زنند.آگاه‌بودن از تعصب‌ها (Biases): انسان تمایل دارد مسائل را ساده ببیند یا گاهی هم بدون دلیل آن را پیچیده‌تر کند. آگاهی از سوگیری‌های شناختی (مثلاً توهم دانایی، ترس از ناشناخته‌ها و ...) می‌تواند کمک کند تا واقع‌بینانه‌تر قضاوت کنیم.به‌عنوان یک رهبر فنی (Technical Lead) در تیم نرم‌افزاری، این چارچوب می‌تواند در تصمیم‌گیری‌ها، مدیریت تسک‌ها، رهبری تیم و حتی در تعیین استراتژی توسعه بسیار راهگشا باشد. در ادامه چند پیشنهاد و راهکار عملی ارائه می‌شود که نشان می‌دهد چگونه می‌توانید از این چارچوب در نقش رهبری فنی استفاده کنید:۱. پایش مداوم و شناسایی نوع مسئلهبهترین کاربرد ساینِفین این است که قبل از هر تصمیم یا اقدام، به‌صورت آگاهانه از خودتان بپرسید:آیا مسئله/تسک، ساده و دارای بهترین‌روش اثبات‌شده (Best Practice) است؟آیا نیاز داریم با متخصصان مشورت کنیم و داده‌ها را عمیق تحلیل کنیم (پیچیده/Complicated)؟آیا نمی‌توان از قبل پاسخ را پیش‌بینی کرد و باید آزمایش و تکرار (Complex) انجام دهیم؟آیا شرایط بحرانی یا فوریتی است و باید بلافاصله عمل کنیم (Chaotic)؟به این ترتیب، شما به‌صورت سیستماتیک یاد می‌گیرید برای هر تسک و چالشی روش متناسبی به کار بگیرید، به‌جای اینکه یک الگوی ثابت برای همه‌ی مسائل تجویز کنید.۲. مدیریت و اولویت‌بندی تسک‌ها بر اساس حوزهدر نقش رهبر فنی معمولاً به شما رجوع می‌کنند که کدام تسک فوری است، کدام تسک پیچیده است و به تحلیل نیاز دارد، و کدام تسک را می‌توان با یک دستورالعمل ساده انجام داد. با بهره‌گیری از ساینِفین می‌توانید:تسک‌های ساده (Obvious) یا روتین را به نیروهای کم‌تجربه یا تازه‌وارد بسپارید تا به‌سرعت کار را یاد بگیرند. این تسک‌ها نباید وقت نیروهای ارشد را زیاد بگیرد.تسک‌های پیچیده (Complicated) را شناسایی کنید و برایشان زمان تحلیل و بررسی کارشناسی کافی بگذارید. اگر لازم است، متخصصان خارجی یا ابزارهای پیشرفته را وارد کنید.تسک‌های با عدم قطعیت بالا (Complex) را با رویکرد «Proof of Concept» یا «MVP» جلو ببرید. از اسپرینت‌های کوتاه و بازخورد مداوم استفاده کنید تا ریسک را کنترل کنید.تسک‌های بحرانی (Chaotic) را فوری در اولویت اول قرار دهید. برنامه‌ها را متوقف کنید و ابتدا بحران را مهار کنید؛ مثلاً باگ تولیدی(Production) یا حمله امنیتی.این کار باعث می‌شود منابع (زمان، نیرو، هزینه) را دقیق‌تر تقسیم کنید و تیم‌تان را کاراتر جلو ببرید.۳. انتخاب روش توسعه و متدولوژی مناسبساینِفین به شما کمک می‌کند تشخیص دهید چه رویکردی در توسعه باید به کار گرفته شود:در مسائل ساده: استفاده از مستندات آماده، چک‌لیست‌ها و Best Practiceهای رایج. مثلاً وقتی می‌خواهید یک API ساده با یک الگوی شناخته‌شده درست کنید.در مسائل پیچیده (Complicated): معمولاً مهندسی پیش از اجرا (Upfront Engineering)، بررسی چندین سناریو و تهیه مستندات طراحی (Design Documents) مفید است.در مسائل پیچیده (Complex): توسعه‌ی چابک (Agile)، اسپرینت‌های کوتاه، ساخت پروتوتایپ و گرفتن بازخورد.در حوزه‌ی آشوبناک (Chaotic): فرایند رسمی را کنار بگذارید و سریع اقدام اضطراری کنید (Hotfix، Rollback و ...).به‌عنوان رهبر فنی، می‌توانید برای هر بخش یا فاز پروژه، متدولوژی منطبق با حوزه‌ی مربوطه را پیشنهاد کنید و از یک روش واحد برای همه‌ی قسمت‌ها استفاده نکنید.۴. آموزش و توانمندسازی تیمبسیاری از مشکلات در توسعه نرم‌افزار زمانی ایجاد می‌شوند که اعضای تیم نمی‌دانند باید از چه رویکرد یا ابزاری استفاده کنند. شما می‌توانید:تیم‌تان را با چارچوب ساینِفین آشنا کنید: در جلسات داخلی، با مثال‌های واقعی از پروژه‌ی خودتان، توضیح دهید که کدام تسک‌ها را می‌توان در حوزه‌ی ساده در نظر گرفت و کدام در حوزه‌ی پیچیده.برای هر حوزه دستورالعمل کلی داشته باشید: مثلاً یک راهنمای مختصر بنویسید که اگر تسک ساده است، راهنمایی اصلی چیست (چک‌لیست‌ها؟ مستندات خاص؟). اگر پیچیده/Complicated است، بهتر است سراغ چه ابزارها یا افراد متخصصی برویم و چه مدت زمان برای تحلیل لازم داریم.چشم‌انداز مشترک بسازید: وقتی همه‌ی اعضا یک زبان مشترک برای توصیف پیچیدگی یا بحران داشته باشند، سریع‌تر و شفاف‌تر می‌توانند در مورد راه‌حل توافق کنند.۵. مدیریت تغییر و نوآوریاغلب رهبران فنی وظیفه دارند تیم را به سمت فناوری‌های جدید، ابزارهای به‌روز یا معماری‌های مدرن سوق دهند. اما میزان ریسک و عدم قطعیتی که هر تکنولوژی جدید به همراه دارد، در ساینِفین می‌تواند به شما نشان دهد در کدام حوزه قرار می‌گیرید:اگر فناوری یا ابزار جدید، تا حد زیادی تست‌شده و سندیت دارد (مثلاً استفاده از یک کتابخانه‌ی محبوب در جامعه‌ی متن‌باز)، این موضوع می‌تواند نزدیک به حوزه‌ی پیچیده (Complicated) باشد و با بررسی کارشناسی سراغش بروید.اگر هنوز ناشناخته است و مطمئن نیستید چه نتایجی خواهد داشت (مثلاً ابزارهای بسیار نوپا، یا ترکیب معماری‌های عجیب‌وغریب)، به حوزه‌ی پیچیده (Complex) نزدیک است و باید با رویکرد آزمایشی (Proof of Concept) عمل کنید.با این شیوه، می‌توانید از پریدن ناگهانی کل تیم به سمت فناوری‌های ناشناخته جلوگیری کرده و ابتدا با چند آزمایش و پروتوتایپ جلو بروید.۶. رسیدگی به بحران‌ها (Incident Management)یکی از وظایف مهم رهبر فنی، مدیریت بحران‌های فنی است. ساینِفین می‌گوید در حوزه‌ی آشوبناک (Chaotic):اولویت اول: اقدام فوری برای جلوگیری از گسترش بحران (مثلاً از دسترس خارج‌کردن سرویس، ری‌بوت سرور، Rollback انتشار جدید و ...).سپس حس کردن (Sense) و تشخیص ابعاد مسئلهدر نهایت پاسخ دادن (Respond) به شکل ساختارمند (مثلاً پس از بازگرداندن شرایط عادی، وارد دلایل ریشه‌ای (Root Cause Analysis) شوید).این رویکرد باعث می‌شود هم سرعت عمل داشته باشید و هم پس از آرامش اولیه، با تحلیل درست، از بروز مجدد مشکل جلوگیری کنید.۷. جلوگیری از سردرگمی (حوزه‌ی Disorder) در تیمحوزه‌ی «نابه‌سامانی (Disorder)» زمانی اتفاق می‌افتد که تیم شما نمی‌داند نوع چالش چیست یا حتی تعریف درستی از مسئله ندارد. به‌عنوان رهبر فنی می‌توانید:تفکیک مسئله به بخش‌های کوچکتر: اگر یک مشکل یا پروژه خیلی مبهم است، سعی کنید اجزایش را جدا کنید و برای هر بخش، یک دامنه یا حوزه‌ (Domain) را تشخیص دهید.شفاف‌سازی نیازمندی‌ها: با ذی‌نفعان (مدیر محصول، کاربران، مشتریان) جلساتی بگذارید تا نیازمندی‌ها را واضح‌تر کنید.همکاری با اسکرام مستر یا مدیر پروژه: اگر در تیم‌تان شخصی برای مدیریت فرایند وجود دارد، با او هماهنگ شوید که در جلسه‌های Grooming یا Planning به تیم کمک کند تا کارها را خوب دسته‌بندی کنند.۸. نظارت و بازنگری مداومساینِفین یک چارچوب پویا است؛ ممکن است مسئله‌ای که ابتدا ساده به‌نظر می‌رسد، ناگهان پیچیده یا حتی آشوبناک شود (یا برعکس). بنابراین، به‌صورت دوره‌ای (مثلاً در جلسات اسپرینت ریویو یا جلسات هفتگی) این سوال‌ها را مطرح کنید:آیا تغییری در وضعیت پروژه یا تیم ایجاد شده که نوع تسک/مسئله را عوض کند؟آیا حوزه‌ی تسک‌ها از Complex به Complicated منتقل شده و حالا دستورالعمل بهتری برایش داریم؟آیا تسک یا مشکل خاصی پیش آمده که باید فوری وارد عمل شویم (Chaotic)؟این بازنگری‌ها به شما امکان می‌دهد رویکرد و منابع‌تان را به‌روز کرده و از غافل‌گیری جلوگیری کنید.جمع‌بندیاستفاده از این چارچوب باعث می‌شود که رهبران و مدیران، به جای تلاش برای تحمیل یک روش ثابت به همه موقعیت‌ها، ابتدا نوع موقعیت را بشناسند و سپس متناسب با آن بهترین سبک رهبری و تصمیم‌گیری را انتخاب کنند.</description><category>Amir Mokarchi</category><author>Amir Mokarchi</author><pubDate>Mon, 13 Jan 2025 15:20:56 +0330</pubDate></item><item><title>پنج سطح جهل The Five Orders of Ignorance</title><link>https://virgool.ir/@mokarchi/پنج-سطح-جهل-the-five-orders-of-ignorance-tix2poecw9t2</link><description>موضوع پنج سطح جهل ابتدا توسط Philip Armour در مقاله‌ای تحت عنوان The Laws of Software Process در سال 2000 ارائه شد. Armour در مقاله خود به این اشاره کرد که:نرم‌افزار منبع دانش است: برخلاف محصولات فیزیکی که ماده‌ی اولیه تولید می‌کنند، نرم‌افزار محصولی از دانش انسان است.فرآیند توسعه نرم‌افزار معطوف به یادگیری است: بسیاری از شکست‌های پروژه‌های نرم‌افزاری به دلیل فقدان درک صحیح از مسئله و ناتوانی در مدیریت دانش رخ می‌دهد.مدیریت جهل مهم‌تر از مدیریت دانش است: برای موفقیت، تیم‌ها باید ابتدا بفهمند که چه چیزهایی را نمی‌دانند.پنج سطح جهل یک چارچوب فکری ارزشمند است که درک بهتری از دانش، نادانسته‌ها، و نحوه یادگیری ارائه می‌دهد. این چارچوب برای توسعه‌دهندگان نرم‌افزار و مدیران پروژه بسیار مفید است، زیرا به درک عمیق‌تر مشکلات، شناسایی خطرات، و مدیریت دانش در فرایند توسعه کمک می‌کند.سطح صفر: دانش (0th Order of Ignorance)شما می‌دانید که چه چیزی را می‌دانید. این دانش شامل مهارت‌ها، مفاهیم، و اطلاعاتی است که به آن‌ها تسلط دارید.مثال عملی:شما می‌دانید که چگونه یک الگوریتم مرتب‌سازی را پیاده‌سازی کنید.می‌دانید که برای رفع یک خطا (bug)، از کدام ابزار (debugger) استفاده کنید.کاربرد: در این سطح، شما در حال استفاده از دانش خود برای حل مشکلات یا انجام کارها هستید.سطح اول: ندانستن (1st Order of Ignorance)شما نمی‌دانید که چه چیزی را نمی‌دانید، اما می‌دانید چگونه بفهمید.ویژگی کلیدی: این سطح به توانایی تحقیق و یادگیری اشاره دارد.مثال عملی:شما می‌دانید که یک فناوری جدید (مثلاً Docker) وجود دارد و نیاز دارید که آن را یاد بگیرید.برای یادگیری، به مستندات رسمی، دوره‌های آموزشی، یا کمک همکاران مراجعه می‌کنید.چالش: این سطح نیازمند زمان و منابع برای یادگیری است.سطح دوم: نادانی درباره نادانی (2nd Order of Ignorance)شما نمی‌دانید که چه چیزی را نمی‌دانید. به عبارتی، «چیزهای ناشناخته ناشناخته» وجود دارند.ویژگی کلیدی: این سطح زمانی رخ می‌دهد که شما حتی نمی‌دانید که باید به دنبال چه چیزی باشید.مثال عملی:شما نمی‌دانید که یک فناوری جایگزین بهتر (مثلاً Kubernetes به جای Docker) وجود دارد.در پروژه، ممکن است تیم متوجه نباشد که یک وابستگی کلیدی وجود دارد که باید مدیریت شود.چالش: این سطح ریسک بسیار بالایی دارد، زیرا ممکن است پروژه را با خطرات غیرمنتظره مواجه کند.راه‌حل: کاوش، تحلیل، و استفاده از تجربیات دیگران می‌تواند به شناسایی این ناشناخته‌ها کمک کند.سطح سوم: فرآیند ندانستن (3rd Order of Ignorance)شما نمی‌دانید که چگونه بفهمید. به عبارتی، فرآیند یا متدی برای شناسایی و یادگیری ندارید.ویژگی کلیدی: این سطح زمانی رخ می‌دهد که تیم یا فرد نمی‌داند از کجا شروع کند.مثال عملی:یک تیم نرم‌افزاری نمی‌داند چگونه نیازمندی‌های مشتری را شناسایی کند.ممکن است فرآیندهای مدیریت پروژه مانند Scrum یا Kanban وجود نداشته باشد.چالش: بدون داشتن فرآیند مناسب، تیم در مواجهه با مشکلات سردرگم می‌شود.راه‌حل: تعریف فرآیندهای یادگیری و تصمیم‌گیری، مانند کارگاه‌های آموزشی (workshops)، جلسات طوفان فکری (brainstorming)، و تحلیل نیازمندی‌ها.سطح چهارم: متافیزیک ندانستن (4th Order of Ignorance)شما حتی نمی‌دانید که جهل وجود دارد.ویژگی کلیدی: این سطح به ناآگاهی مطلق اشاره دارد. فرد یا تیم حتی متوجه نمی‌شود که باید چیزی را یاد بگیرد یا تغییر دهد.مثال عملی:یک سازمان معتقد است که فرآیندهای فعلی آن‌ها کامل هستند و نیازی به بهبود ندارند.یک مدیر پروژه ممکن است فکر کند که مشکلات تیم ناشی از کم‌کاری است، در حالی که دلیل واقعی ضعف فرآیندهاست.چالش: این خطرناک‌ترین سطح است، زیرا تغییر تنها زمانی رخ می‌دهد که این سطح جهل شناسایی شود.راه‌حل: استفاده از مشاوران خارجی، بازخورد مشتریان، و تحلیل عملکرد سازمان.جنبه‌های عملی‌تر این چارچوب :تیم‌ها باید به یادگیری مداوم متعهد باشند.تیم‌ها باید به صورت فعالانه ناشناخته‌ها را بررسی کرده و با آن‌ها مواجه شوند.ترکیب افراد با دیدگاه‌ها و تخصص‌های مختلف می‌تواند به کاهش جهل در همه سطوح کمک کند.جمع‌بندی: چگونه از این چارچوب استفاده کنیم؟شناسایی سطوح جهل در پروژه:بررسی کنید که تیم در کدام سطح از جهل قرار دارد.برنامه‌ریزی برای کاهش جهل:سطح صفر: استفاده از دانش موجود.سطح اول: تحقیق و یادگیری.سطح دوم: تحلیل نیازمندی‌ها و پیش‌بینی ناشناخته‌ها.سطح سوم: تعریف فرآیندهای یادگیری و تحلیل.سطح چهارم: بازنگری عمیق و مشاوره خارجی.تمرکز بر یادگیری مداوم:تیم‌ها باید همیشه آماده یادگیری، تحقیق، و بازنگری فرآیندها باشند.کاربرد ابزارهای مناسب:استفاده از User Story Mapping برای کاهش سطح دوم جهل .استفاده از Scrum یا Kanban برای کاهش سطح سوم جهل.استفاده از Retrospective و External Audit برای شناسایی سطح چهارم جهل.</description><category>Amir Mokarchi</category><author>Amir Mokarchi</author><pubDate>Mon, 13 Jan 2025 15:01:23 +0330</pubDate></item><item><title>مفهوم کلی انتزاع و کپسوله سازی در Repository و UnitOfWork</title><link>https://virgool.ir/@mokarchi/مفهوم-کلی-انتزاع-و-کپسوله-سازی-در-repository-و-unitofwork-jalerlhdbdcl</link><description>در این یادداشت به باید ها و نباید ها،الگو ها و ضدالگوها اشاره ای نمی شود و صرفا به بررسی مفاهیم پایه ای برنامه نویسی شی گرا در قالب Repository و Unit Of Work می پردازیم. پایه و اساس مطلب فوق برگرفته شده از دوره کپسوله سازی entity framework آقای Vladimir Khorikov می باشد و همچنین دارای ارجاعات متعددی به مقالاتی در این زمینه در وب می باشد تا حد ممکن سعی شده است که به منابع در پایان یادداشت اشاره شود.کپسوله سازی (Encapsulation) چیست؟ایده کپسوله سازی (Encapsulation) در مورد محتوی یک شی(Object) است. نه تنها برای نگه داشتن آنها، بلکه برای محافظت از آنها می باشد. بعضی مواقع تعریفی که از کپسوله سازی میبنید ممکن است Information Hiding یا مخفی کردن اطلاعات باشد یا حتی در کنار هم قرار دادن داده ها و یا عملیاتی که روی داده ها انجام میشود و یا به اصطلاح Bundle کردن داده ها باشد.هر چند که این دو تکنیک میتوانند کپسوله سازی رو ایجاد کنند اما Encapsulation این نیست.کپسوله سازی یا Encapsulation به معنای محافظت کردن از جامعیت داده ها یا Data Integrity است. یعنی یک کلاس وقتی به خوبی کپسوله شود داده های درونی یا Internal Data آن نمیتواند درون یک مقدار یا حالت Inconsistent  یا ناسازگار یا نامعتبری قرار بگیرد. یعنی محافظت از جامعیت و صحت داده ها که به آن Encapsulation یا کپسوله سازی گفته می شود.همانطور که ذکر شد  Information Hiding و Bundle کردن داده ها و یا عملیاتی که روی داده ها انجام میشود در کنار هم به کپسوله سازی کمک میکند. Information Hiding داده های درونی رو از دید کلاینت های آن کلاس مخفی میکند و قرار دادن داده ها و Operation در کنار هم یک نقطه ورود یگانه ایجاد میکند برای تمامی عملیاتی که میتواند روی کلاس انجام گیرد.به این ترتیب شما میتوانید قبل از اینکه اقدام به تغییر دادن State  یا داده های یک کلاس بکنید چک انجام بدهید و Integrity آن داده هایی که قرار هست در واقع درون کلاس شما قرار بگیرد را بررسی کنید.در بحث کپسوله سازی Invariant  ها هم مطرح میشود. Invariant یعنی یک سری شروط که باید در تمامی اوقات برقرار باشد. به عنوان یک برنامه نویس شما باید کاری کنید که هیچ کدام از Invariant ها هیچ وقت نقص نشوند و این وظیفه شماست که تمهیدات لازم برای یک همچنین کاری رو در نظر بگیرید.انتزاع (Abstraction) چیست؟بزرگ کردن ضروریات و حذف کردن نامرتبط ها تعریف کامل و جامعی از Abstraction می باشد که توسط رابرت مارتین ارائه شده است.وقتی شما یک کدی مینوسید روش های نامحدودی برای نوشتن یک برنامه دارید بعضی از زبان های برنامه نویسی هم Turing-complete هستند که این اجازه رو به شما میدهد که یک برنامه را به n  روش مختلف پیاده سازی کنید.در سبک برنامه نویسی Freestyle شما این امکان رو خواهید داشت که کل برنامه رو با یک کلاس و یک متد پیاده سازی کنید که مسلما اشتباه است به این علت که ذهن انسان محدود می باشد و همزمان قادر به مدیریت اطلاعات محدودی می باشد به همین علت هم هست که کلی روش و راهنمای نوشتن برنامه خوب بوجود آمده است تا سطح Productivity ما رو بالا ببرد. چون با کاهش سطح بهره وری امکان اشتباه ما بالا میرود و به عبارت دیگر ما با این ساختار باید جلوی پیچیدگی کد رو گرفته و کد برنامه را قابل مدیریت کنیم.انتزاع یا Abstraction هم اشاره دارد به اینکه به جای تمرکز بر روی مجموعه ای از کارها به صورت همزمان فقط و فقط بر روی یک موضوع متمرکز شود و آنچه که فعلا موضوعیت ندارد رو در نظر نگیرد و یا به عبارت دیگر برنامه ات را به قطعات کوچیکتر شکسته و روی هر کدام به صورت مجزا متمرکز شود.انتزاع یا Abstraction میتواند سلسله مراتب هم داشته باشد. یعنی Abstraction ای سوار بر Abstraction های دیگر که این به شما کمک میکند ایده های پیچیده تان را به سطوح مختلف شکسته و در هرکدام از سطوح فکر کنید و کد بزنید.انتزاع های سطح پایین رو lower-order abstraction و انتزاع های سطح بالا رو higher-order abstraction می گویند.این سلسله مراتب کمک میکند که شما تمرکز کنید که در هر لحظه در یک سطح کد برنید و به سطح دیگر فکر نکنید و درگیر جزئیات سطوح دیگر نشوید.چه تفاوتی بین Encapsulation و Abstraction وجود دارداین دو مفهوم گره خورده بهم هستند ولی تفاوت های زیادی نیز باهم دارند. Encapsulation درمورد سازگاری دیتا صحبت میکند در حالی که Abstraction  به بزرگنمایی ضروریات و حذف کردن نامرتبط ها اشاره دارد.کمکی که Abstraction به ما میکند این می باشد که دیگر نگران اینکه عملیاتی که انجام میدهیم معتبرهست یا نه نیستیم و این وظیفه را به عهده Encapsulation میگذاریم و تمرکز را بر روی آنچه که کد انجام میدهد و نه چگونگی آن قرار میدهیم.الگوی Repository چیست؟وظیفه اصلی این الگو این است که تمامی کار های مربوط به دیتابیس را در یک محیط یکسان متمرکز کند و در سرتاسر برنامه پخش نباشد و اجازه دسترسی در سرتاسر برنامه و از هرجایی به دیتابیس را نتوانید پیدا کنید.ریپازیتوری ها با استفاده دامین کلاس ها، نه دیتابیس آبجکت ها ارتباط برقرار میکنند.یعنی StudentRepository اگر متد GetById داشته باشد یک instance از student به عنوان یه دامین کلاس برای شما return میکند.به عبارت دیگر ریپازیتوری ها نه تنها کد دسترسی به داده را دارند مثلا کوئری های SQL را داخل خودشان قرار میدهند بلکه Mapping بین دامین مدل و دیتابیس را نیز انجام میدهند. هدف این پترن این است که دسترسی به داده ها را برای شما ساده تر کند و داده هایی که داخل دیتابیس هستند و دامین آبجکت هایی که داخل دیتابیس هستند را براحتی واکشی کند که اصلا شما مجبور نباشید بدانید که آیا این دامین آبجکت ها از داخل دیتابیس یا مثلا از درون رم و یا ... واکشی می شوند.همه این موارد را تجمیع و Abstract میکند. پس تمام جزئیات پیاده سازی با این پترن Abstract میشوند.حالا بیاید برای روشن تر شدن قضیه به این کد یک نگاه بیندازیم. https://gist.github.com/mokarchi/a484d21b926d0141a99a2cce29c02484 اگر بخواهیم این قطعه کد رو با Repository جایگزین کنیم چنین تغییری خواهم داشتStudent student = _repository.GetById(id);میبینید که این دو قطعه کد تفاوت چندانی با هم ندارن. پراپرتی Student از نوع DbSet است و کل متد هایی که برای student در یک Repository میتوانید قرار بدهید در این نوع وجود دارد مثل find,add,update و ...اینجاست که اختلاف نظر ایجاد Repository ها بوجود میاد از یک طرف طرفدارن Repository معتقد هستن که میبایست همه دیتابیس اکسس کد درون Repository قرار بگیرد و از طرفی کسانی که با DbSet و EF کار میکنند اذعان دارند که DbSet به خودی خود Repository است پس نیازی به ایجاد Repository دیگری نیست.هر دو این نوع تفکر تا حدودی درست می باشد. پترن Repository و ایده پشت آن برای کار کردن با دیتابیس ها مفید است ولی خیلی قبل تر از معرفی ORM هایی مثل EF شکل گرفته است و امروزه با وجود ORM های پرقدرتی مثل EF شاید خیلی استفاده از این پترن مفید نباشد.حالا سوالی که مطرح هست این است که باید از کدام روش استفاده کنیم. از DbSet ها استفاده کنیم یا نه بریم یک لایه Abstraction دیگه اضافه کنیم و از Repository های سفارشی خودمون استفاده کنیم. این بسته به نوع پروژه شما دارد.به عبارت دیگه پترن Repository مباحث مربوط به persistence یا ذحیره کردن اطلاعات داخل دیتابیس رو abstract میکنه پس Repository یک Abstraction است.برای مثال پیچیدگی مربوط به بازیابی یک student با استفاده از شناسه اون و یا اضافه کردن یک student را abstract میکند. کاری که DbSet هم انجام میدهد. بنابراین اگر پروژه شما نیاز به پیچیدگی بیش از حدی ندارد عملا نیازی به اضافه کردن Abstraction جدید و اضافه کردن یک لایه Repository جدید ندارید.ولی اگر پروژه شما دارای پیچیدگی ای بیشتر از آنچه هست که DbSet ها در اختیار شما قرار میدهند اضافه کردن یه لایه Abstraction جدید میتواند مفید باشد.حالا چطور پیچیدگی های برنامه را مدیریت کنیم.با اضافه کردن سلسله مراتب Abstraction روی همدیگر. به این شکل که Abstraction های سطح بالاتر وابسته به Abstraction های سطح پایین تر شوند.فقط باید این را در نظر بگیرید که فقط زمانی منطقی هست که شما Repository ها را اضافه کنید که واقعا رسالت مخفی کردن یکسری پیچیدگی ها را برعهده داشته باشند. کلاس هایی که شامل پیچیدگی های اضافه ای نیستن و هیچ چیزی را abstract نمیکنند به Abstraction های کم عمق معروف هستن.(Shallow abstractions)استفاده از Repository های جنریک یا غیر جنریکسازگاری یا consistency یا به عبارتی یک شکل بودن باعث میشود که من توصیه کنم همیشه از Repository های غیر جنریک استفاده کنید.وقتی شما همیشه از Repository های غیر جنریک استفاده میکنید آگاهید که همیشه از برگ های سلسه مراتب Repository و اون درخت Repository تون رو استفاده میکنید.خیلی خوبه که به صورت Explicit تمامی Repository هاتون رو بررسی کنید و ببینید که چه Repository های توی کد بیس تون وجود دارند. ایده کلی اینه که Aggregate Root ها توی بحث DDD نیاز به Repository دارند.کلاس های غیر برگ در این سلسه مراتب باید به صورت یک کلاس Abstract تعریف شود که امکان استفاده به صورت مستقیم فراهم نباشد. این موضوع برای Repository های جنریک هم صدق می کند.در نهایت باید به این نکته توجه داشته باشید که شما باید به دید صرفا یک Abstraction بهش نگاه کنید. مثلا فرض کنید تا الان استراتژی حذف شما به صورت Physical (حذف واقعی از دیتابیس) بوده و اکنون میخواین اون رو به حذف Logical (حذف منطقی توسط IsDelete) تغییر بدین. در این صورت باید تمام جا هایی که مستقیما از متد Removeخود DbSet استفاده میکردین رو تغییر بدین و این تغییر در یک پروژه بزرگ دردسر زیادی رو به همراه داره، در صورتی که استفاده از یک Abstraction کار رو بسیار ساده میکرد.درواقع به جای اینکه مستقیما با DbContext و DbSet ها سرو کار داشته باشیم بهتره یک لایه انتزاعی (Abstraction) روی اون ایجاد کنیم و همه جا از اون Abstraction استفاده کنیم، یعنی به جای اینکه در همه جای پروژه متد Remove خود EF رو صدا بزنیم، اون رو داخل کلاس Repository نامی بنویسیم و همه جا متد Delete ریپازیتوری رو فراخوانی کنیم. این باعث میشه اگه یه روزی لازم شد متد Delete ریپازیتوری رو سفارشی کنیم و تغییر بدیم، اون تغییر تو کل پروژه اعمال بشه، چرا که تو کل پروژه از متد Delete ریپازیتوری استفاده کردیم.به همین ترتیب اگر نیاز به سفارشی سازی متد های دیگر (مثلا Add یا Update) دارید (مثلا اعمال اعتبارسنجی خاص به هنگام افزودن و ویرایش یا لاگ گرفتن تغییرات به هنگام ویرایش و... ) فقط کافیه متد های اون رو داخل Repository تغییر بدین و نه اینکه مجبور باشین تو کل پروژه کد هاتون رو تغییر بدین.الگوی Unit Of Workهمانطور که پیشتر اشاره شد زمانی ما از یک Abstraction استفاده میکنیم که یک Abstraction سطح بالا یکسری از پیچیدگی های سطح پایین تر رو abstract کرده باشد وقتی خود DbContext یک Unit Of Work هست دلیلی نداریم که یک Unit Of Work تعریف کنیم. با این پیاده سازی عملا دچار Abstraction های کم عمق می شویم که با عنوان Shallow abstractions با اون آشنا شدیم. در سناریو هایی که پیچدگی بر روی DbContext بیش از حد می شود Unit Of Work از حالت shallow خارج شده و پیاده سازی اون توجیح پذیر می شود.هنگامی که شما از EF استفاده می‌کنید و یک DbContext را وهله سازی می‌کنید، در واقع یک Unit Of Work می‌سازید. در عمده سناریو ها نیاز هست تا داده های زیادی از پایگاه داده فراخوانی شده و سپس در برخی از آن ها تغییراتی بدهیم، داده ای را اضافه کنیم و داده های دیگر ( مثلا نامعتبر ) را حذف کنیم. طبیعتا نمی توانیم به ازای هر تغییر و هر بار افزودن و حذف داده ها، بلافاصله و تک به تک، داده ها را به سمت پایگاه داده ارسال کنیم. چرا که این امر هم موجب کاهش کارایی و مصرف منابع خواهد شد و هم ممکن است در حین ثبت داده ها ناگهان خطایی رخ دهد و باقی تغییرات در پایگاه داده منعکس نشوند و خاصیت تراکنشی (Transactional) بیزینس از بین برود.الگوی Unit Of Work راهکاری را ارائه می دهد که در آن تمامی تغییرات داده شده در مدل، مانیتور می شوند. یعنی دقیقا در جایی ثبت می کنیم که چه مشخصاتی از چه اشیایی تغییر کرده، چه اشیایی اضافه شده و چه اشیایی حذف شده اند. سپس در انتها و پس از انجام کارها، با صدا زدن متد Save خواهیم فهمید که باید چه تغییراتی را به سمت پایگاه داده ارسال کنیم و البته این کار هم به صورت Transactional انجام خواهد گرفت.اگر کلاس Unit Of Work شما ارجاعی به تمام Repository های شما دارد طبیعاتا نقض اصل Abstraction می باشد. به این علت که Unit Of Work یک Abstraction سطح پایین می باشد ولی Repository ها Abstraction سطح بالا می باشد. با استناد به این دانش که Unit Of Work بدون Repository میتواند کار کند ولی Repository بدون Unit Of Work نمیتواند کار کند.همانطور که میدانید ارتباط بین Abstraction های سطح بالا و سطح پایین همیشه یک طرفه است از سطح بالا به سطح پایین. بنابراین بجای استفاده از DbSet ها باید از نوع جنریک اون استفاده بشه حالا بنظرتون این همون اتفاق قبلی نیست. DbContext همچنان به DbSet دسترسی داره؟تفاوت اینجا این هست که DbSet جنریک یه Abstraction سطح پایین تر نسبت به DbContext هست. این کار عینا استفاده از یک اینترفیس بجای کلاس concrete می باشد.اگر صرفا برای دست یابی به الگوی &#34;Context Per Request&#34; یا &#34;Session Per Request&#34; از Unit Of Work استفاده میکنید باید بدونید که اینکار نه توسط Unit Of Work و یا حتی خود EF بلکه توسط سیستم تزریق وابستگی و در اصل توسط IOC Container ها اتفاق میافته.درواقع IOC Container هست که میدونه باید برای هر درخواست (یا اصولا Scope)، فقط و فقط یک DbContext ساخته بشه (به جای اینکه چندین DbContext ایجاد بشه!)اگه بخوایم دقیق تر بحث درخواست و Scope رو باز کنیم باید بگیم که Scope یک &#34;محدوده&#34; هست که وقتی ایجاد میشه، اشیایی که درون اون ایجاد میشوند داخل همون Scope (محدوده) قابل استفاده هستند و در واقع &#34;زنده&#34; هستند و پس از پایان اون محدوده (Scope)، تمام اشیایی که در اون Scope ایجاد شده اند نیز &#34;میمیرند&#34; (در واقع Dispose میشوند و از بین میروند)البته تمامی این حرف ها &#34;فقط&#34; برای اشیایی صادق است که Lifetime (بازه عمر) آنها به صورت Scope تنظیم شده باشند.حال جالبه بدونین که IOC Container میاد و در ابتدای یک درخواست وب (Request)، یک Scope ایجاد میکنه و در پایان اون درخواست وب، اون Scope رو از بین میبره (در نتیجه تمام اشیایی آن Scope هم از بین میروند)در این حالت وقتی ما DbContext رو به صورت Scope (درواقع با Lifetime یا همون بازه عمر برابر با Scope) تعریف میکنیم، اتفاقی که میافته اینه که IOC Container در ابتدای هر درخواست، یک Scope ایجاد میکنه و درنتیجه DbContext ما هم (که قبلا به صورت Scope تنظیم شده است)، فقط و فقط یک نسخه از آن داخل Scope مربوطه (که اول درخواست ساخته شده) ایجاد میشه؛ در نتیجه طی اون Scope ما هر چندبار هم که DbContext رو فراخوانی کنیم، توسط سیستم تزریق وابستگی، &#34;فقط و فقط&#34; همون یک نسخه اولیه به ما ارجاع(پاس) داده میشه و در این حالت الگوی Context Per Request تحقق میابد.در پایان درخواست وب هم، چون Scope مربوطه ازبین میره، تمامی اشیای داخل آن(ایجاد شده توسط آن Scope) نیز از بین میروند از جمله همین DbContext ما و درواقع در پایان درخواست، DbContext ما هم Dispose میشهمنابع:https://www.pluralsight.com/courses/ef-core-6-encapsulating-usagehttps://www.dntips.ir/https://t.me/c/1029399467/77614</description><category>Amir Mokarchi</category><author>Amir Mokarchi</author><pubDate>Sun, 16 Apr 2023 11:07:36 +0330</pubDate></item><item><title>کیفیت کد خود را تقویت کنید</title><link>https://virgool.ir/@mokarchi/کیفیت-کد-خود-را-تقویت-کنید-hbsk42l8mp0m</link><description>اگر مجبورید کلاسی را با آمدن یک ویژگی جدید تغییر دهید، ممکن است اصل SRP را نقض کرده باشید. به طور معمول، هر زمان که شما نیاز به پیاده سازی cross-cutting concerns ها مانند logging، caching و غیره داشته باشید، این اتفاق می افتد.ما با ایجاد دو کلاس مجزا refactoring را انجام دادیم. یکی برای تزئین (decorate) دیگری استفاده می شود. توجه داشته باشید که همچنین یک اینترفیس را استخراج و کلاس decorator نمونه ای از اینترفیس را به عنوان یک وابستگی در نظر می‌گیریم. به همین راحتی می توانید یک کلاس را تزئین (decorate) کنید.می‌بینید که UserRepository چقدر ساده است، و حالا فقط یک مسئولیت دارد؟ Logging دیگر نگرانی نیست.ما یک کلاس UserRepositoryLoggingDecorator جداگانه ایجاد کرده‌ایم که از logging مراقبت می‌کند.کلاس‌های موجود را تغییر ندهیداین اصل مورد علاقه من است. اینکه بتوانید فقط کلاس های جدید را اضافه کنید و کلاس های موجود را لمس نکنید، بسیار عالی است.شما به سرعت نقض OC را تشخیص می دهید. هر ویژگی جدید نیاز به یک if جدید دارد. درست مانند کلاس ProductFormatter، که یک نوع product را می‌گیرد و رشته‌ای را که به روشی دلخواه قالب‌بندی شده است را برمی‌گرداند.در ابتدا خیلی بد به نظر نمی رسد.با این حال، برای هر نوع قالب بندی جدید، شما باید OCP را زیر پا بگذارید. همچنین، اگر اشکالی وجود دارد و باید منطق قالب بندی را اصلاح کنید، باید این کار را در جایی که توسط کد غیر مرتبط احاطه شده‌است انجام دهید.استفاده از polymorphism برای حذف if-else  دیوانه کننده و غیر ضروری، یکی از بهترین و آسان‌ترین روش‌ها است. به این ترتیب، شما به اصل Substitution Liskov دست می‌زنید. اکنون، ما کد غیرقابل انعطاف بالا را refactor کرده ایم.بنابراین، شما به وضوح متوجه شده اید که اکنون چقدر کد بیشتری وجود دارد. Refactoring به معنای کوچک کردن کد نیست، بلکه در مورد ایجاد کدهایی است آسان‌تر که با عقل و منطق کنار بیاید.ابتدا هر تکه منطقی را داخل if و else-if قرار می دهیم و آن را در داخل کلاس formatter قرار دهیم. اکنون هر کلاس یک هدف واحد دارد. زمانی که شما نیاز به رفع یک باگ دارید، می دانید که تمام کدهای اطراف به آن مربوط می شود.ثانیاً، هر formatter با فراخوانی RegisterFormatter آن در ProductFormatter فراخوانی می‌شود.پیاده‌سازی Format در حالی که خود قالب‌بندی را کنترل می‌کند، برای استفاده از جستجوی formatter  تغییر داده شده‌است.همچنین، توجه داشته باشید که اکنون یک JSON formatter وجود دارد. که به سادگی با اضافه کردن یک کلاس برای آن مدیریت می شود.در اینجا مثالی از نحوه استفاده از product formatter آورده شده است.فقط از مواردی استفاده کنید که مربوط به کلاس شما استشما احتمالاً از کلاس های استفاده کرده اید یا حتی ساخته اید که مشابه چاقوی سوئیسی عمل می کنند.به اندازه کافی عمومی برای هر چیزی. آنها اساساً بدردنخور هستند.فرض کنید ما یک کلاس داریم که برای به روز رسانی یک کاربر استفاده می شود. این کلاس به یک UserManager وابسته است که شامل مهم ترین و اصولی ترین ویژگی های یک چیز است.همه چیز عالی است اما، ما می توانیم بهتر عمل کنیم.در حال حاضر، کلاس UpdateUser می تواند آزادانه به هر روشی که توسط user manager در معرض نمایش قرار می گیرد دسترسی داشته باشد. دقیقاً آن چیزی نیست که ما می خواهیم، درست است؟ما با یک ابزار تک منظوره مانند آنچه در قسمت پایین آمده، وابستگی به چاقو سوئیسی را عوض می‌کنیم.توجه کنید که چگونه UpdateUserCommand و UserManager تقریباً بدون تغییر باقی مانده است.پاک کردن کدهای کثیف به همین سادگی است.کلاس های خود را مجزا (decouple) کنیدشما قبلاً در این مقاله با اصل وارونگی وابستگی آشنا شده اید. همه چیز در مورد تکیه کردن به انتزاعی در کلاس های concrete است. بنابراین، کلاس زیر چندین اصل را نقض می کند. وابستگی خود به AppDatabase را «new» می کند.به‌جای «new» کردن در نمونه‌های عینی، آنها را به‌عنوان وابستگی‌های صریح و روشن در نظر می‌گیرید، و می‌خواهید به جای یک کلاس مشخص، بر انتزاع تکیه کنید. به بیان ساده، شما می خواهید یک interface را به عنوان آرگومان سازنده در نظر بگیرید.به این کلاس GetUsersCommand بهبود یافته نگاهی بیندازید.«new» کردن کلاس ها را متوقف کنید و interface ها را به عنوان آرگومان های سازنده در نظر بگیرید. انصافاً به همین سادگی است.&#34;تعداد کلاس ها با هر refactor که شما انجام می دهید افزایش می یابد!&#34;این ممکن است یکی از اعتراضات شما به رویکرد refactoring باشد. به یاد داشته باشید که refactoring به معنای کوچک کردن کد یا حتی لزوماً ساده‌تر کردن همه چیز نیست. این در مورد تغییر کد شما برای مطابقت با پیچیدگی برنامه و تسهیل کار با کد است.متن فوق برگرفته شده از مدیوم Nicklas Millard می باشد</description><category>Amir Mokarchi</category><author>Amir Mokarchi</author><pubDate>Mon, 20 Dec 2021 13:09:40 +0330</pubDate></item></channel></rss>