<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
    <channel>
        <title>نوشته های mostafa vakili</title>
        <link>https://virgool.io/feed/@mostafavakily</link>
        <description>mostafavakili.ir</description>
        <language>fa</language>
        <pubDate>2026-06-19 11:45:36</pubDate>
        <image>
            <url>https://files.virgool.io/upload/users/31825/avatar/avatar.png?height=120&amp;width=120</url>
            <title>mostafa vakili</title>
            <link>https://virgool.io/@mostafavakily</link>
        </image>

                    <item>
                <title>تبدیلType استفاده شده در  Expression ها با استفاده از ExpressoinVisitor</title>
                <link>https://virgool.io/apieco/%D8%AA%D8%A8%D8%AF%DB%8C%D9%84type-%D8%A7%D8%B3%D8%AA%D9%81%D8%A7%D8%AF%D9%87-%D8%B4%D8%AF%D9%87-%D8%AF%D8%B1-expression-%D9%87%D8%A7-%D8%A8%D8%A7-%D8%A7%D8%B3%D8%AA%D9%81%D8%A7%D8%AF%D9%87-%D8%A7%D8%B2-expressoinvisitor-owvsgfqebx2n</link>
                <description>اگه بخوام ادامه مسیر قبلی رو برم و طبق قولی که دادم بودم عمل کنم امروز میخوام توضیح بدم چطوری Expression ها رو از یه نوعی به نوع دیگه تبدیل کردم, ولی قبلش به نظرم بهتره تا کمی دلیل این کار رو توضیح بدم بعد ادامه بدم, وقتی قرار شد تا فریم ورک موجود رو بهبود بدم و اصلاح کنم یه موضوعی بود که باعث شده بود تا کلی کد اضافی داخل این پروژه زده بشه, برنامه نویس های قبلی سعی کرده بودن زیر ساخت رو طراحی کنن که کسی که داره لایه سرویس رو مینویسه بر اساس مدل های خودش Expression ها رو بنویسه و همون رو به لایه رپوزیتوری بده و این Expression ها به صورت خودکار به مدل های دیتابیسی مپ بشن ولی موفق نشده بودن واسه همین بعد از گذشت یه بازه زمانی به این نتیجه رسیده بودن که باید کلاس های پایه سرویس و رپوزیتوری جدید اضافه کنن  و کلی از کد ها رو عوض کنن , درنهایت ما کلی متد داشتیم که کار نمیکرد و وقتی یه نیروی تازه وارد میخواست روی این کد ها توسعه انجام بده بدون خبر داشتن از این ماجرا میومد کلی کد میزد و موقع اجرا میدید که همه چیز به خطا میخوره و باید حتمادقت میکرد که از کدوم کلاس های پایه داره ارث بری میکنهخب مشکل اصلی چی بود, تیم قبلی تصمیم میگیره تا لایه Repository رو کامل از لایه سرویس جداکنه, پس تصمیم میگیره تا یه کلاس مدل رو تعریف کنه که صرفا مدل های Entity framework رو شامل بشه و اومده بود یه سری کلا های جدید تعریف کرده بود که توی لایه Service و به عنوان ViewModel ازش استفاده کرده بود  تمام ورودی های مربوط به Service ها از نوع ViewModel بود و تمام ورودی های Respository  از نوع Model, خب این معماری تنها تا وقتی که تنها عملیات Crud مد نظر بود خیلی خوب عمل میکرد ولی از یک جایی به بعد این نیاز توی پروژه ها به وجود اومده بود که یک سری متد داشته باشیم که قرار بود یک سری Expression رو دریافت کنن و بر اساس اون داده ها رو فیلتر کنن, که باعث شده بود کلا ساختار ها به هم بریزه برای این که درک بهتری از این موضوع داشته باشین تصویر پایین رو ببینیدهمون طوری که توی تصویر بالا میبنید ما یک Expression داریم که برا اساس ViewModel ساخته شده و چیزی که باید به متد LoadDb بدیم حتما باید از نوع Model باشه.خب برای اینکه بدونین این رو چطوری هندل کردیم کلاس های پایین رو در نظر بگیرین, من اسامی رو طوری انتخاب کردم که قابل درک باشه(من اینجا مدل ها رو خیلی ساده کردم و تنها هدفم نشون دادن روش هستش نه تمام کدی که پیاده سازی شده)خب الان میخوایم این Expression رو که بر اساس ViewModel پیاده سازی شده رو به صورت خودکار تبدیل کنیم به یه Expression دیگه بر اساس Model:برای این که بتونیم این کار رو انجام بدیم اولین چیزی که نیاز داریم این هستش که یک کلاس برای این منظور طراحی کنیم که باز من رفتم سراغ کلاس های Generic:یه متد به منظور تبدیل به صورت استاتیک اضافه کردیم(اگر میخواین دلیلشو بدونین بهتره مقاله قبلی رو بخونین), کاری که باید انجام میدادیم این بود که اول نوع ورودی رو پیدا کنیم و پارامتر جدید رو بر اساس اون تشکیل بدیم, وقتی پارامتر جدید رو بر اساس Model ایجاد کردیم باید یک زیر ساختی داشته باشیم که کل بدنه این Expression رو پردازش کنه و عملیات تبدیل رو انجام بده, وقتی این تبدیل روی بدنه درخواست انجام شد در نهایت Body جدید رو با پارامتر تعریف شده ترکیب میکنیم تا به یه Expression جدید از نوع Model برسیم و برگردونیم و به راحتی میدیمش به لایه Repositoryو اما چطوری Body رو تبدیل کردیم, وقتی که Linq و ExpressoinTree معرفی شد هدفش این بود که برنامه نویس بتونه داخل کدهاش کد بنویسه و بتونه در زمان اجرای کدهای جدید ایجاد و اجرا بکنه, برای اینکه بشه این ساختار رو در زمان اجرا هم پردازش کرد و بشه تغییراتی رو بهش اعمال کرد توی دات نت 3.5 یک کلاسی معرفی شد به اسم ExpressionVisitor, این کلاس شامل تمام متد های مورد نیاز برای پردازش node های مربوط به Expression tree هستش و به ما اجازه میده هر تغییری رو توی هر سطحی که بخوایم روی Expression انجام بدیم.خب با وجود همچین کلاسی کار ما خیلی ساده تر شد و اومدیم کلاس پایین رو ایجاد کردیم که کار Convert رو برامون انجام میداددر نهایت نتیجه این تغییرات موقع اجرا شد چیزی که دنبالش بودیم: فعلا این باشه تا یادم بود بعدا ویرایش کنم و مطالب رو کمی بیشتر بازش کنم</description>
                <category>mostafa vakili</category>
                <author>mostafa vakili</author>
                <pubDate>Wed, 24 Jul 2019 17:31:39 +0430</pubDate>
            </item>
                    <item>
                <title>کلاس های Generic در خدمت پرفورمنس</title>
                <link>https://virgool.io/@mostafavakily/%DA%A9%D9%84%D8%A7%D8%B3-%D9%87%D8%A7%DB%8C-generic-%D8%AF%D8%B1-%D8%AE%D8%AF%D9%85%D8%AA-%D9%BE%D8%B1%D9%81%D9%88%D8%B1%D9%85%D9%86%D8%B3-pkiaddyglrdh</link>
                <description>توی توییتر قول داده بودم اولین چیزی که مینویسم یه موضوع دیگه ای باشه ولی خب دیدم نوشتن اون مطلب یه خورده زمان بیشتری میخواد و الان وقت کافی برای اون ندارم گفتم خب پس بزار یه موضوع دیگه رو بنویسم که در ادامه مطلب قبلی باشه.در ادامه بهبود فریمورکی که قبلا در موردش صحبت کردم رسیدم به جاییی که دیدم برای اضافه کردن یه فرم Crud کلی باید کلاس اضافه کنیم به پروژه, که شامل کلاس های مربوط به مدل, سرویس, repository, ایجاد گرید, ایجاد کلاس هایی مخصوص combobox(یه چیزی مثل select2 که کاملا سفارشی توی فریم ورک ایجاد شده), بعد از کلی کلنجار رفتن با این مسئه که چرا اصلا!!! باید همچین کارهایی کرد اونم جایی که واقعا خیلی از متدها اضافی هستش و نیازی به این کار نیستش, اومدم یه تغییراتی توی ساختار پروژه ایجاد کردم که وقتی میخواستیم فقط یه گرید, فرم سرچ روی گرید و عملیات های حذف و اضافه و ویرایش داشته باشیم به جای اینکه مجبور بشم 15 تا کلاس بنویسیم فقط یه کلاس مدل داشته باشیم با controller مربوطه و تمام(کاری ندارم که این کار رو چطوری انجام دادم چون خارج از بحث این مطلب هستش).خب کار رو شروع کردم و برای این که بتونم به چیزی که میخوام روی این ساختار کاملا Generic برسم این بود که باید سرویس هایی که به صورت خودکار در زمان اجرا ایجاد میشدن میفهمیدن که مدل اصلی کدومه, مدل مربوط به کنترل های جستجو کدومه و ....برای این که پاراگراف بالا رو درک کنید بزاریم با یه مثال ادامه بدم, فرض کنید به ما گفتن خب تا الان بلاگ نداریم و میخوایم بلاگ رو هم به پروژه اضافه کنیم تا خبرها رو از طریق اون منتشر کنیم, اولین کاری که هر برنامه نویس سی شارپ که از EF توی پروژه خودش استفاده کرده اینه که بیاد کلاس پایین رو ایجاد کنه:کلاس ها رو ساده در نظر میگیرم فعلاخب بعدش کلاس های مورد نیازمون رو ساختیم تا بتونیم این رو توی یه جدولی به مدیر سایت نمایش بدیم, بعد از تمام شدن این مرحله به ما میگن یه فرم جستجو هم بزارین بالای این جدول تا بر اساس عنوانی که وارد میکنیم بتونیم جستجو رو هم انجام بدیم, خب برای این کار مجبور شدیم بیایم یه مدل برای این صفحه ایجاد کنیم:تا اینجای کار هیچ مسئله خاصی وجود نداشت چون توی حالت عادی ما میایم همین مدل رو از UI میگیرم میدیم به سرویس و اونم با استفاده از این آیتم ها لیست رو فیلتر میکنه و نتیجه رو برمیگردونه, اما توی ساختار خودمون این بخش رو به کل حذف کرده بودیم و قرار نبود اصلا کسی برای این بخش کدی بنویسه(هدف ما هم از اول همین بود که کدهای این سبکی رو حذف کنیم که سریعتر بتونیم پروژه رو توسعه بدیم).خب الان از کجا بدونیم چه سرویسی قراره این مدل رو بگیره و چه کاری باهاش انجام بده! ساده ترین کار این بود که بیایم از Attributeها استفاده کنیم و یه خورده کلاس هامونو باهوش تربیت کنیم مثل کاری که Ef توی کلاس اول انجام داد و فهمیدم که این مدل قراره به کدوم جدول وصل بشه, تغییرات رو دادیم و کلاس نهایی شد این شکلی:خب این طوری مسئله حل شد, توی زیر ساخت خودمون وقتی درخواست رسید سمت سرور میدونستیم که قراره این رو به چه سرویسی ارسال کنیم, برای این که بخوایم این مدل رو تشخیص بدیم از چی استفاده کردیم؟ بله ساده ترین روش اولین روش میشه, رفتیم سراغ Reflection و با کمک این تیکه کد کلاس اصلی رو پیدا میکردیم باهاش:تو یکی از مطالب قبلی نوشتم که این کد چقده توی دنیای واقعی کند عمل میکنه و برای این که ببنیم چقده سربار داره به کارمون اضافه میکنه روی سیستم خودم(انصافا خیلی سیستم خوبی هم هستش) دیدم هر بار که یه درخواست جدید میرسه و میخوایم با کمک این قسمت بدونیم این مدل مربوط به کدوم کلاس هستش دیدیم متوسط چیزی نزدیک به 5500 نانو ثانیه زمان لازم داره, خب اگه این روش این همه زمان لازم داره حتما روش های هستش که زیر 100 نانوثانیه زمان لازم داشته باشه(چون این مقاله رو روی لپ تاپم که ضعیف هستش دارم مینویسم خروجی زمان ها رو نمیزارم چون خیلی بیشتر از این اعداد میشه)دومین راه ساده برای حل این مسئله این بود که دست به گریبان ساختار Dictionary بشم که سر زمان خیلی کمک بزرگی بود, در نهایت کد بالا به شکل زیر تغییر کرد:این بار وقتی کد رو اجرا کردم توی اجرای اول خب تغییر خاصی اتفاق نیفتاد ولی سر درخواست های بعدی که مکررا داشت ارسال میشد این زمان رسید به چیزی در حدود 35 نانوثانیه, که خب خیلی توی زمان اجرا تاثیر داشت یعنی چیزی در حدود 157 بار سریعتر اجرا شدن در درخواست های بعدی!!! ولی این روش یه مشکل جدی داشت و اونم این بود که داشت مصرف Memory رو بالا میبرد, عملا مشکل رو از یه نقطه برداشتم و فرستادم یه نقطه دیگه(یهو یادم افتاد مرغ و خروس ها چطوری جای خودشون رو تمیز میکنن)وقتی به این نقطه رسیدم ظاهرا تمام چیزی که میخواستم بهش رسیده بودم ولی واقعیت این بود که هنوز خیلی جای کار داشت, پس دست به دامن خود سی شارپ شدم, وقتی داشتم کد های خود سی شارپ رو توی گیت هاب میخوندم که ببینم هر قسمتی رو چیکار کردن که سریعتر شده به یه کلاس خیلی جالب خوردم:این کلاس تمام چیزی که لازم داشتم رو به من داد, اومدم و یه کلاس جدید ساختم که هنوز از همون Reflection استفاده میکرد اما این بار به صورت generic و static و در نهایت شد این کلاس:خب حالا نوبت اجرای پروژه با این کد بود, وقتی اجرا کردم دیدم متوسط زمان لازم برای پیدا کردن مدل اصلی از روی SearchContext نزدیک 4 نانوثانیه شد!!!! یه بار دیگه مموری رو هم بررسی کردم و بر خلاف روش دوم سربار مموری هم وجود نداشت.ولی چه چیزی باعث شد که حتی بتونیم از Dictionary هم سریعتر باشیم؟اولین موضوع این هستش که وقتی داریم از Dictionary استفاده میکنیم برای افزودن و یا جستجوی یه آیتم باید سربار محاسبه هش کد رو هم لحاظ کنیم, مورد دوم که اصلی ترین مورد هستش مربوط به ماهیت خود سی شارپ هستش, کلاس داخلی BaseModelTypeFinder به صورت Generic هستش و چون Static هستش باعث میشه تا در زمان اجرا به ازای هر T یک Type جدید برامون ایجاد کنه و اگر دقت کنین ModelType رو هم به صورت Readonly ایجاد کردم تا فقط در زمان ایجاد این Type یک بار صدا زده باشه.یه مقایسه ای هم روی لپ تاپم انجام دادم تا بتونم یه خروجی نمایش بدم:با Stopwatch این مقایسه رو انجام دادم که خب ممکنه توی سیستم های مختلف عدد های یکسانی نیاد</description>
                <category>mostafa vakili</category>
                <author>mostafa vakili</author>
                <pubDate>Thu, 18 Jul 2019 15:42:13 +0430</pubDate>
            </item>
                    <item>
                <title>تغییر در مقادیر متغیر های private</title>
                <link>https://virgool.io/@mostafavakily/%D8%AA%D8%BA%DB%8C%DB%8C%D8%B1-%D8%AF%D8%B1-%D9%85%D9%82%D8%A7%D8%AF%DB%8C%D8%B1-%D9%85%D8%AA%D8%BA%DB%8C%D8%B1-%D9%87%D8%A7%DB%8C-private-j07eh5rkkmza</link>
                <description>چند وقت پیش توی یکی از شرکت های ایران استخدام شدم و از همون روز روی پروژه های مختلف مشغول فعالیت شدم تا بعد از حدود یک سال روی یکی از پروژه ها موندگار شدم, ه رچی حجم داده های داخل دیتابیس بیشتر و بیشتر میشد(برخی از جداول بالای چند میلیارد دیتا) یک چیزی توی سیستم داشت خودنمایی میکرد, اون هم کند شدن بیش از حد سیستم بود مخصوصا وقتی قرار بود گزارش بگیریم, کاری که انجام دادم بهبود سرعت این پروژه و اعمال یک سری تغییرات در سطح فریم ورک بود که باعث شد در بعضی قسمت های پروژه تا ده برابر سرعت بیشتر بشه و توی بعضی صفحات مدت زمان انتظار از بیست دقیقه برسه به حدود سه ثانیه, امروز گفتم یکی از این کارهارو که باعث افزایش سرعت و پرفورمنس شد رو بنویسم.از اونجایی که این پروژه روی یک فریم ورک اختصاصی که داخل شرکت پیاده سازی شده بود اولین قدم برای من آنالیز کردن پروژه بود تا بفهمم عملیاتی که میخوام سرعتش رو بهبود بدم چی هستش, برای این که بتونم به حداکثر پرفورمنس مد نظر خودم برسم متوجه شدم تو یکی از پروژه ها برنامه نویس قبلی اومده یکی از فیلد ها private رو با کمک reflection دستکاری میکنه و همین موضوع یکی از دلایل کند بودن اجرای متد بودش(شاید اعداد و ارقامی که میخوام بنویسم اولش بگین چند نانوثانیه هیچ تاثیری نداره ولی قسمت اول رو دوباره بخونین تا دستتون بیاد که همین نانو ثانیه ها وقتی برای حجم بالای دیتا باشه چه تاثیری روی پروژه داره)برای این که متوجه بشین دقیقا داستان چی بود تصویر زیر رو نگاه کنیدخب همون طوری که توی بالا میبیند یک کلاس داریم که یه متغیر private داخلش هستش که برنامه نویس قبلی به خاطر نیاز پروژه باید حتما این مقدار رو تغییر میداد یا یه آبجکت جدید از این کلاس ایجاد میکرد چون سربار ایجاد آبجکت جدید خیلی بالا بود اومده بود با reflection مقدار این متغیر رو تغییر میداد که موفق هم شده بود که پرفورمنس رو بالا ببره ولی این روش خیلی هم بهینه نیستشخب تصویر بالا کدی بود که اولین بار نوشته شده بود و زمان اجرای این کار هم روی سیستم من حدود 1440 نانوثانیه بوداومدم اول این کد رو کمی بهینه تر کردم و field lookup رو کش کردم تا فقط یک بار در زمان اولین اجرا درست بشه که نتیجه شد کد زیر:و بعد از اجرا کردن این متد نتیجه اجرا هم شد حدود 1332 نانوثانیه,این کد هم سریعتر از کد قبلی اجرا شد و هم بدنه متد خیلی تمیزتر ولی باز هم جوابگوی کار ما نبودتوی واقعیت فقط  چند درصد کد ما سریعتر شده بود ولی این سریع بودن خیلی به چشم کاربر نمیومد و باز راضی کننده نبود, به خاطر همین مجبور شدم یه کار دیگه بکنم, یه خورده با کد ها سر و کله زدم دیدم با استفاده از Expression و Reflection اجرای کد سریعتر از این نمیشه, خب یه انتخاب جدید پیش روم بود باید انتخابش میکردم, دستکاری مستقیم متغیر با استفاده از کد های IL, دست به کار شدم و نتیجه شد کد زیر:وقتی این پروژه رو اجرا کردم چیزی که دیدم شدیدا هیجان زده ام کرد, زمان اجرای این کد فوق العاده تر از اون چیزی هستش که میشه تصور کرد در حدود یک و نیم نانوثانیه برای این که ببینم این کد چقده سریع هستش اومدم یه متغیر دیگه داخل کلاس تعریف کردم و از نوع public گذاشتمش و کد رو اجرا کردمدست آخر همه کد ها رو گذاشتم کنار هم و اجرا کردم تا نتیجه رو راحت تر بشه مقایسه کرد:همون طوری که توی عکس میتونید ببینید همین یک تغییر کوچیک باعث شد تا کد نزدیک به 1440 بار سریعتر اجرا بشه, شاید بگین این اعداد به نانوثانیه هستش و اصلا به چشم نمیاد ولی کافیه در نظر بگیرین وقتی که حداقل دیتایی که قراره این عملیات روش انجام بشه به یک میلیون رکورد برسه و قرار باشه این عملیات تکراری فقط روی یک فیلد انجام بشه میشه حدود یک و نیم ثانیه و اگر قرارباشه این عملیات رو مانند چیزی که توی پروژه ما بود(ایجاد یه آبجکت و مقدار دهی همه متغیرهاش به متد اول) برای یک کلاس با بیست تا فیلد میشه حدود 30 ثانیه</description>
                <category>mostafa vakili</category>
                <author>mostafa vakili</author>
                <pubDate>Wed, 26 Jun 2019 16:44:46 +0430</pubDate>
            </item>
                    <item>
                <title>الگوی طراحی Object pool</title>
                <link>https://virgool.io/@mostafavakily/%D8%A7%D9%84%DA%AF%D9%88%DB%8C-%D8%B7%D8%B1%D8%A7%D8%AD%DB%8C-object-pool-h0fgddyeotu0</link>
                <description>امروز تصمیم گرفتم تا در رابطه با الگوی طراحی Object pool مطلبی بنویسم و تجربیاتم رو از استفاده این الگو به اشتراک بزارم. من سعی میکنم تا میتونم نوشته ها رو خلاصه کنم و با طرح مسئله ای که منجر به بروز الگو شده مطلب رو توضیح بدم تا درک اون ساده تر بشه و اگر جایی نیاز به کدزنی باشه از سی شارپ برای این کار استفاده میکنم.چند سال پیش قرار شد تا یه نرم افزار گرافیکی طراحی کنم, بعد از گذشت یه بازه زمانی متوجه شدم اپلیکیشن به نسبت کند هستش, مجبور شدم بشینم کد رو مرور کنم, مصرف مموری و cpu رو کامل بررسی کنم, خیلی سریع دیدم که توی بخشی از کد ها نرم افزار نیاز داره تا از یک نوع کلاس آبجکت های زیادی رو تولید میکنه که بعد از ایجاد آبجکت و استفاده خیلی سریع اون آبجکت Dispose میشه, مشکل از همینجا شروع میشد که Initialize کردن این آبجکت زمان زیادی میگرفت و طول عمر آبجکت خیلی کوتاه!(تا اینجا رو داشته باشید تا بریم سراغ مسئله بعدی)یک مثال دیگه که ما خیلی به این الگو نیاز پیدا میکنم نرم افزار هایی هستش که در اون  socket connections های زیادی رو باید هندل کنیم(برای این که از بحث دور نشیم بیشتر این موضوع رو باز نمیکنم)خب تا اینجا دیدم که مسئله اصلی چی بود که باعث شد تا نرم افزار گرافیکی ما کند بشه, نوبت حل مسئله رسید, اینجا بود دست به دامن یک الگوی طراحی به اسم Object pool شدیم. اگه بخوام تو یه خط توضیحش بدم:این الگوی طراحی رو توی موقعیت هایی استفاده میکنیم که زمان ایجاد یک آبجکت خیلی بالا باشهروشی که برای حل این مسئله پیشنهاد میشه این هستش که ما میایم یک Container ایجاد میکنیم که شامل یک تعداد مشخصی از آبجکت هایی هستش که زمان ایجاد بالایی رو دارن, وقتی جایی نیاز به آبجکتی از کلاس مربوطه داشته باشیم از این Container برمیدارم و تا زمانی که کارمون باهاش تموم نشده فقط و فقط در اختیار ما هستش و بعد از این که کارمون باهاش تموم شد برش میگردونیم قرارش میدیم توی Container.نمودار Uml این الگو به این شکل هستشدر اینجا کلاس Client کلاسی هستش که نیاز به استفاده آبجکت داره,  Reuseable کلاسی هستش که زمان Initialize کردن بالایی داره(برای مثال SqlConnectin, ایجاد Thread و یا کلاس گرافیکی نرم افزار ما) و در آخر  کلاس ReusablePool اصلی ترین کلاس توی این الگو هستش, این کلاس شامل لیستی از آبجکت هایی هستش که میتونیم به کلاس Client بدیم و لیستی از آبجکت هایی که در حال استفاده هستند.مزایای این الگو چی هستش؟تاثیر خیلی زیادی روی Performance دارهقابلیت استفاده مجدد از آبجکت های ایجاد شده و Share کردن آبجکت رو در زمان اجرای برنامه به ما میدهکی از این الگو استفاده کنیم؟در صورتی که توی کد خودتون جایی دیدید که از یک نوع آبجکت تعداد زیادی new و Dispose میکنیددر صورتی که بدونیم تعداد محدودی از آبجکت ها داریم که همزمان با هم استفاده میشندیک مثالی که برنامه نویس های دات نت و جاوا خیلی باهاش درگیر هستن ایجاد آبجکتی برای اتصال به دیتابیس هستش, در صورتی که برنامه ما اتصال به دیتابیس زیادی داشته باشه ایجاد connection جدید و از بین بردن اون شدیدا روی کارایی برنامه تاثیر منفی میزاره و توان سیستم در پردازش تعداد درخواست همزمان رو به شدت پایین میاره و موضوع دوم هم اگر ما همزمان connection های باز زیادی داشته باشیم یک سربار به دیتابیس اضافه میشه که باعث میشه تا دیتابیس هم تحت تاثیر قرار بگیره.برای حل این مشکل توی سی شارپ از کلاسی مثل زیر استفاده میکنیم: public class ObjectPool&lt;T&gt;
    {
        private ConcurrentBag&lt;T&gt; _objects;
        private Func&lt;T&gt; _objectGenerator;

        public ObjectPool(Func&lt;T&gt; objectGenerator)
        {
            if (objectGenerator == null) throw new ArgumentNullException(&quot;objectGenerator&quot;);
            _objects = new ConcurrentBag&lt;T&gt;();
            _objectGenerator = objectGenerator;
        }
        public T GetObject()
        {
            T item;
            if (_objects.TryTake(out item)) return item;
            return _objectGenerator();
        }
        public void PutObject(T item)
        {
            _objects.Add(item);
        }
    }دلیل استفاده از ConcurrentBag این هستش که میخوایم به صورت Parallel کد رو اجرا کنیم. در اینجا صرفا یه لیست ایجاد کردیم و زمانی که نیاز به یه آبجکت داشته باشیم و در لیست وجود نداشته باشه یه آبجکت جدید ایجاد میکنیم و وقتی کارمون با آبجکت تموم شد توی لیست قرارش میدیم تا درخواست بعدی از آبجکت استفاده کنه.برای این که تاثیر این الگو رو ببیند من سعی کردم تا کلاسی که ایجاد میکنم مصرف مموری بالایی داشته باشه: class MyClass
    {
        public int[] Nums { get; set; }
        public long GetValue(long i)
        {
            return Nums[i];
        }
        public MyClass()
        {
            Nums = new int[100000];
            Random rand = new Random();
            for (int i = 0; i &lt; Nums.Length; i++)
                Nums[i] = rand.Next();
        }
    }همون طوی که میبینید این کلاس هم مصرف حافظه بالایی داره هم زمان ایجاد یک آبجکت جدید از این کلاس زمان زیادی رو میگیره(روی سیستم من چیزی در حدود 4 میلی ثانیه), خب بریم سراغ کد اصلی که میخواد از ترکیب این دو استفاده کنه:            ObjectPool&lt;MyClass&gt; pool = new ObjectPool&lt;MyClass&gt;(() =&gt; new MyClass());
            Parallel.For(0, 10000, (i, loopState) =&gt;
            {
                MyClass mc = pool.GetObject();

                Console.CursorLeft = 0;
                Console.WriteLine(mc.GetValue(i));

                pool.PutObject(mc);
            });
ده هزار آبجکت رو به صورت همزمان توی ترد های مختلف اجرا میکنیم و سعی میکنم از object pool استفاده کنیم, برای این که تاثیر این کار رو ببینم سعی میکنم همین تعداد آبجکت رو در حالت عادی هم ایجاد کنیم: for (int i = 0; i &lt;= 10000; i++)
            {
                MyClass mc = new MyClass();
                Console.WriteLine(mc.GetValue(i));
            }من این دو تا کد رو اجرا کردم و  میزان مصرف حافظه هر دو رو با همدیگه مقایسه کردم اگر دوست داشتین خودتون میتونیم زمان اجرا رو هم خودتون مقایسه کنید:در صورت استفاده از object poolدر صورت عدم استفاده از Object pool</description>
                <category>mostafa vakili</category>
                <author>mostafa vakili</author>
                <pubDate>Mon, 04 Mar 2019 18:18:12 +0330</pubDate>
            </item>
                    <item>
                <title>ایجاد آبجکت بدون صدا زدن سازنده در C#</title>
                <link>https://virgool.io/@mostafavakily/%D9%85%D8%AE%D8%AA%D8%B5%D8%B1%DB%8C-%D8%A7%D8%B2-c-%D8%AF%D8%A7%D8%AA-%D9%86%D8%AA-jeuz30p30mez</link>
                <description>امروز چون فرصت ویرایش و انتشار چندتا مطلبی که توی ویرگول گذاشتم رو ندارم تصمیم گرفتم تا چند تا نکته از داخل سی شارپ بنویسم.موضوع اولی که میخوایم امروز باهاش سر و کله بزنیم این هستش که چطوری میتونیم آبجکتی رو ایجاد کنیم بدون این که بخوایم سازنده کلاس اون رو صدا بزنیم!قبل از این که بخوایم ادامه بدیم بهتره ببینیم اصلا برای چی باید این کار رو انجام بدیم؟! یه مثال ساده ای که بخوایم بزنیم مواقعی هستش که میخوایم تا عملیات deserialization رو انجام بدیم, در این مواقع چون باید Property ها رو به صورت دستی مقدار دهی کنیم نیازی به صدا زدن سازنده نیست, و عملا سرباز اضافی محسوب میشه(فرض کنید میخواین یه رشته از Json رو deserialize کنید)هدف ما ایجاد یک آبجکت از کلاس User هستش و میخوایم سازنده این کلاس اجرا نشه در نتیجه اگه توی محیط کنسول کار کنیم نباید عبارت Constructor توی خروجی چاپ بشه. برای این منظور از متد GetUninitializedObject که در فضای نام System.Runtime.Serialization قرار داره استفاده میکنیم:نتیجه اجرای کد بالا یک آبجکت از نوع کلاس User هستش که سازنده اون اجرا نشده هستش و خط Console.WriteLine(o) چیزی که در خروجی چاپ میکنه متن User خواهد بود که نشون دهنده Type آبجکت هستش.نقطه مقابل این متد برای ایجاد آبجکت ها در زمان اجرا یا Run-Time متد Activator.CreateInstance هستش که باعث صدا زدن Constructor میشه. دلیل این که از روش اول برای ایجاد آبجکت در زمان اجرا میکنیم سرعت بالاتر اون هستش که برای مثال بالا در صورتی که از GetUninitializedObject استفاده کنیم(روی سیستم من) در حدود 12 نانوثانیه زمان لازم بود تا آبجکت ایجاد بشه در صورت استفاده از Activator.CreateInstance 490 نانو ثانیه زمان لازم بود و در صورتی که آبجکت رو به صورت مستقیم و به شکل زیر ایجاد کنیم:			var u = new User();متوسط زمان لازم حدود 300 نانو ثانیه بود.</description>
                <category>mostafa vakili</category>
                <author>mostafa vakili</author>
                <pubDate>Sun, 03 Mar 2019 15:08:24 +0330</pubDate>
            </item>
                    <item>
                <title>API Versioning</title>
                <link>https://virgool.io/apieco/api-versioning-kxstlpgkdija</link>
                <description>من خودم چندین سال هستش که دارم برنامه نویسی میکنم و توی این چند سال بار ها و بار ها پیش اومده که برای بعضی پروژه ها نیاز بوده تا Api بدم, خیلی وقت ها پیش میاد که این Api مربوط میشه به یه اپ موبایلی, توی نسخه های اولیه که شما Api رو آماده میکنین همیشه بعضی قسمت ها هستش که نادیده گرفته میشه و دلایل خاص خودش رو داره(ممکنه به خاطر عدم پشتیبانی اون قسمت توی اپلیکیشن باشه یا به خاطر درخواست مدیرتون که میخواد محصول سریعتر وارد بازار بشه) چیزی که مشخص هستش اینه که این محصول وارد بازار میشه و ممکنه نسخه اولیه محصول موبایلی شما تعداد زیادی دانلود بگیره و بعد از مدت کوتاهی مجبور بشین که یه سری متد جدید به Api هاتون اضافه کنین و یا توی پارامتر های بازگشتی خودتون تغییری بدین تا با نسخه های جدیدتر اپلیکیشن سازگار باشه و همین نقطه آغاز شروع مشکل میشه.و اما چه مشکلی؟ اگر رابط کاربری شما تغییر کنه و فیلد هایی بهش اضافه بشه و یا فیلد هایی کم بشه و یا اگر برنامه نویس موبایل شما با استفاده از Reflection سعی کرده باشه تا دیتایی رو که دریافت میکنه تبدیل به مدل های مورد استفاده خودش بکنه در این صورت هر تغییری در Api باعث از کار افتادن نسخه های قبلی تر اپلیکیشن شما میشه, ولی خب راهکار چیه؟ نمیتونیم که منتظر معجزه بمونیم که همون لحظه که Api جدید و نسخه جدید رو گذاشتیم بالا همه سریع به روز رسانی کنن(ممکنه کسی که از Api شما استفاده میکنه چندین سازمان یا شرکت مختلف باشن و صرفا یه موبایل اپلیکیشن نباشه!) یا ممکن هستش که شما تغییری توی پارامتر های ورودی Api ها داده باشین و مقادیر ارسالی به سمت متد های شما باعث بروز خطا بشهروشی که برای این منظور پیشنهاد شده به روش زیر هستش: فرض کنید ما یه سرویسی نوشتیم که به صورت Rest Api کار میکنه و قراره یک آی دی بگیره و اطلاعات کاربر رو برگردونه, توی نسخه اول دو فیلد نام و نام خانوادگی رو برمیگردونیم, و در نسخه دوم یک فیلد تصویر هم به اون اضافه کردیم اما در نسخه سوم نام و نام خانوادگی رو ترکیب کردیم و به جای برگردوندن آدرس تصویر که در نسخه دوم داشتیم این بار میخوام محتوای تصویر رو به صورت Base64 برگردونیم؛ به این منظور ما برای هر تغییر جدیدی که میدیم باید یک ورژن جدید ایجاد کنیم:http://virgool.io/api/customers/1234http://virgool.io/api/v2.0/customers/1234http://virgool.io/api/v3.0/customers/1234این روش باز خودش مشکل آفرین میشه چرا که نیاز داره تا ما هم به مشتری ها همواره اعلام کنیم نسخه جدید ایجاد شده نسخه های قدیمی تر نگه داری بشن و ....یکی از روش هایی که خودم بعد مطالعه در موردش واقعا بهش علاقه مند شدم و به نظرم به اندازه کافی هوشمندانه هستش راهکاری هستش که تلگرام برای نسخه بندی Api های خودش در نظر گرفته هستش.برای این کار تلگرام اومد و یک استاندارد به اسم Tl-Schema تعریف کرد, که همه تعاریف متد هاشو برد داخل این Schema, و در مرحله بعدی اومد مفهومی به اسم  SupportedLayer و  SecretSupportedLayer  رو به Api خودش اضافه کرد, به این صورت که مقادیری که داخل این فیلد ها ارسال میشه باعث میشه تا Api متوجه بشه که قراره از کدوم Schema استفاده کنه.در این مطلب قصد ندارم وارد جزئیات عملکردی MTProto بشم به خاطر همین سعی میکنم خیلی خلاصه توضیح بدم, کاری که تلگرام انجام داده به شکل زیر هستش که شما میای یک سری اعداد هگز رو به عنوان اسم متد بهش ارسال میکنی( به عنوان مثال  0x8c718e87  به معنی پیغام هستش)messages.dialogs#15ba6c40 dialogs:Vector&lt;Dialog&gt; messages:Vector&lt;Message&gt; chats:Vector&lt;Chat&gt; users:Vector&lt;User&gt; = messages.Dialogs;messages.dialogsSlice#71e094f3 count:int dialogs:Vector&lt;Dialog&gt; messages:Vector&lt;Message&gt; chats:Vector&lt;Chat&gt; users:Vector&lt;User&gt; = messages.Dialogs;---functions---messages.getDialogs#191ba9c5 flags:# exclude_pinned:flags.0?true offset_date:int offset_id:int offset_peer:InputPeer limit:int = messages.Dialogs;حالا وقتی که میخوایم Api رو صدا بزنیم مقدار مربوط به SupportedLayer در بخشی از این پیامی که داریم به سمت سرور ارسال میکنیم قرار میگیره, با این روش دیگه نیازی نیست که بخوایم دامنه های مختلف برای Api در نظر بگیریم چه اپلیکیشن و یا چه سازمانی بخواد از نسخه Api استفاده کنه فقط در صورتی که خودش به نسخه جدید به روزرسانی کرده باشه با تغییر این مقدار به آخرین عددی که ما به عنوان آخرین لایه معرفی کردیم میتونه با نسخه به روز شده کار کنه</description>
                <category>mostafa vakili</category>
                <author>mostafa vakili</author>
                <pubDate>Fri, 15 Feb 2019 14:54:10 +0330</pubDate>
            </item>
                    <item>
                <title>الگوی استراتژی چیست؟</title>
                <link>https://virgool.io/@mostafavakily/%D8%A7%D9%84%DA%AF%D9%88%DB%8C-%D8%A7%D8%B3%D8%AA%D8%B1%D8%A7%D8%AA%DA%98%DB%8C-%DA%86%DB%8C%D8%B3%D8%AA-jq6kbwkdtrof</link>
                <description>چیزی که ما تا الان شنیدم در مورد شی گرایی اینه که خیلی خوبه و همیشه کار راه انداز هستش, ولی واقعیت اینه که همیشه این طوری نیست که بخواد کار راه انداز باشه و باعث کاهش حجم کد بشه اتفاقا بعضی جاها ممکنه استفاده از ویژگی های شی گرایی باعث افزایش حجم کد و سخت تر شدن نگه داری کد بشهفرض رو میزاریم که به ما گفتن قراره یه سیستم نرم افزاری جدید طراحی کنیم( اینجا سعی میکنم اول با یه بازی شروع کنیم تا بعدا اگه فرصت شد توی دنیای واقعی این مسائل رو مطرح کنیم) وقتی میریم و در مورد این سیستم صحبت میکنیم متوجه میشیم که قراره یه بازی خیلی ساده طراحی کنیمحالا این بازی چی هستش ؟ قرار شده یه بازی جنگ ستارگان طراحی کنیم(حالا چرا این بازی؟ آبجکت هایی که داریم داخل بازی به مرور هم پیچیده تر میشن هم سلاح های جدید به بازی اضافه میشه همون چیزی که باعث میشه ارث بری عملا باعث افزونگی کد ها و سخت تر شدن نگه داری برنامه بشه)خب توی این بازی ما نیاز به یه سری اسلحه این بازی داریم که ما اسمشو میزاریم Weapon, چیزی که تا اینجا مشخص هستش اینه که اولین متدی که توی این کلاس لازم داریم متدی برای شلیک هستشالان ما خیلی راحت میتوینم کلاس های مختلف اسلحه خودمون رو داشته باشیم و از این کلاس ارث بری کنیم, ولی نه صبر کنید, اگه ما یه سبک اسلحه جدید بخوایم به سیستم اضافه کنیم که یه متد دیگه لازم داشته باشه باید چیکار کنیم؟ آیا باید به این کلاس پایه اضافه کنیم یا باید یه کلاس جدید تعریف کنیم و از اون ارث بری کنیم؟برای ساده تر شدن درک این مسئله در نظر  بگیریم که اسلحه های کلاسیکی که میخوایم استفاده کنیم تنها نیاز به شلیک دارن ولی اسلحه های مدرن کلاس 1 نیاز به Init شدن دارن, بعد از مدتی کلاس 2 هم به این دسته اضافه میشن که به غیر از Init شدن نیاز دارن تا متد دیگه ای به اسم Targeting بهشون اضافه بشه که وظیفش هدف گیری خودکار هستش, چه اتفاقی میفته اگه کلاس اسلحه های لیزری به این دسته اضافه بشه که به غیر از Shoot نیاز به یه متد دیگه به اسم Connect داشته باشه؟(اسم متد ها همه نمونه هستش خیلی روی عناوین متد ها حساسیت به خرج ندین)تا اینجای کار ما به چند حالت مختلف رسیدیم: 1) متدی که توی همه زیر کلاس هایی که از Weapon ارث بری کرده لازم هستش, 2) متد هایی که فقط تو یه سری از کلاس ها فقط لازم هستش و ممکنه توی شاخه های مختلف بعضی از کلاس ها اصلا به متد هایی که Parent اون کلاس لازم داشته نیاز پیدا نکنهاینجا همون جایی هستش که مشکل به وجود میاد و باعث میشه به فکر یه راهکار دیگه باشیم و سعی کنیم از ارث بری استفاده نکنیمخب از اونجایی که فکر میکنم ممکنه خود این مثال یه خورده فهم مسئله رو خیلی آسون نکنه از یه مثال دیگه که فقط تصویرش پایین هستش استفاده میکنم:این هم مثالی از یک بازی جنگی که در اون بعضی متد ها توی بعضی زیر کلاس ها اضافی هستشتوی مثال بالا فرض کنین که فقط Ryu توی این بازی قادر هستش که پرش کنه و عملا این متد برای Ken و ChunLi اضافه هستش, یا ChunLi و Ryu فقط نیاز به متد Kick دارن, خب الان یه مشکل دیگه ای که بهش برمیخوریم این هستش که ضرباتی که قراره ChunLi بزنه باعث انتقال برق به بدن حریف بشه در حالی که ضربات Ryu ساده هستشاگه کمی به این دو تا مثال بیشتر دقت کنید متوجه میشن که مشکل از کجا شروع میشه, اگه بخوایم توی یه جمله خلاصه کنیم:اگه توی ساختار ارث بری به متد هایی برسیم که فقط توی یه درصد خاصی از کلاس ها به اون ها نیاز داشته باشیم این مشکل بروز میکنه.بنابراین یه بار دیگه کد هاتون رو نگاه کنین و اگه جایی دیدین که مجبور شدین متدی رو پیاده سازی بکنین که بر فرض مثال در 40 درصد کلاس ها استفاده بشه و یا به متدی رسیدین که مجبور شدین توی چند کلاس مختلف کپی پیست کنین ادامه این آموزش رو بخونین چون میخوایم این مشکل رو حل کنیم.برای حل این مشکل یک روش کلی مطرح شد با اسم Strategy Patternکلید گم شده این مسئله مفهومی هستش به اسم Composition, در مواردی که نیاز داشته باشیم تا یک سری کد رو فقط توی کلاس های مشخصی استفاده بکنیم به جای ارث بری وظیفه اجرای کد های مورد نظر رو به استراتژی میسپاریم, قبل از این که بخوام توضیحات اضافه تری بدم نمودار مربوط به این الگو رو نگاه کنید:تا شده سعی کردم از نمودار هایی استفاده کنه که واضح باشهبرای رفع این مشکل ما اومدیم و رفتار هایی که میدونستیم باعث بروز این مشکل میشند رو جدا کردیم و برای اونها اینترفیس های مربوطه رو طراحی کردیم و یک آجکت از اینترفیس رو توی کلاس پایه قرار دادیم, در مرحله بعدی رفتارهایی که نیاز داشتیم رو توی کلاس های جدیدی طراحی کردیم که قراره بعدا به کلاسی که نیاز به این رفتار داره تزریق کنیم, از اونجایی که قراره استراتژی به صورت Interface و یا Abstract class پیاده سازی بشه ما هر رفتاری که نیاز داشته باشیم میتونیم به کلاس های استفاده کنه تخصیص بدیم تا در زمان اجرا بسته به شرایط رفتار مشخصی اجرا بشه.صادقانه بخوایم برخورد کنیم این روش هم مشکلات خاص خودش رو داره:همه استراتژی ها باید مشخص شده باشند از اونجایی که استراتژی به صورت interface و یا abstract هستش احتمال این که برنامه نویسی فراموش کرده باشه متد های خودش رو پیاده سازی کنه و بروز مشکل بشه وجود داردو اما مهم ترین مشکل این هستش که در زمان اجرا حداقل باید دو آبجکت ایجاد کنیم در حالی که اگه از استراتژی استفاده نکنیم فقط نیاز به یه آبجکت داریماولی مشکلات رو گفتیم الان بریم ببینیم چه مزایایی رو در اختیار ما قرار میده:از اونجایی که الگوری استراتژی به صورت interface هستش میتونیم چندین رفتار جداگانه برای برنامه تعریف کنیم و در زمان اجرا به کلاسمون بگیم رفتارهای مختلف توی شرایط مختلف از خودش نشون بدهمیتونیم رفتارهای جدید رو بعدا به سیستم اضافه کنیم بدون این که نیاز باشه تغیری توی هیچ کدوم از کلاس های قبلی بدیممیتونیم الگوریتم های که توی یه خانواده قرار میگیرین رو با ارث بری پیاده سازی کنیم و توی موقعیت های مختلف استفاده کنیم(این رو باید با مثال عملی بعدا توضیح بدم)چون رفتار ها توی کلاس هایی غیر از Context قرار داده تغییر در اونها نیازی به تغییر در Context نداره(فرض کنیم که SaveBehaviour داریم که تا الان تصاویر رو توی FileStream ذخیره میکرد و میخوایم تصاویر به جای ذخیره شدن در فایل در دیتابیس ذخیره بشه, در این صورت بدو نیاز به تغییر کلاس اصلی محل ذخیره سازی تغییر میکنه)و ...چون مطلب طولانی شد فقط برای تموم کردن این مطلب یه تصویر از یه مسئله واقعی که میتونه به کمک این الگو پیاده سازی بشه رو قرار میدم.این فقط یک نمونه از استفاده از این الگو در دنیای واقعی هستش که میتونیم در نظرش بگیریم(مسئله محاسبه هزینه رفتن از مقصد A به مقصد B) و توی پایین چند دسته مسئله که باید از این الگو استفاده کنیم:جایی که نیاز به الگوریتم های مرتب سازی داشته باشیماعتبار سنجی داده ها, مخصوصا زمانی که قوانین اعتبار سنجی پویا و نامشخص هستشبازی هاذخیره سازی داده هاقسمت هایی که نیاز به Export دیتا وجود داشته باشهاگر خواستین میتونین فکر کنین و مسئله های دیگه ای که میتونه ازاین الگو استفاده کنه رو همین جا بنویسداگر فرصتی شد توی یک مثال عملی این الگو رو توی مقاله دیگه ای می نویسم.</description>
                <category>mostafa vakili</category>
                <author>mostafa vakili</author>
                <pubDate>Wed, 13 Feb 2019 20:58:11 +0330</pubDate>
            </item>
            </channel>
</rss>