Software Philosophy – Telegram
Software Philosophy
3.45K subscribers
160 photos
41 videos
1.54K links
چکیده‌ای از مفاهیم به روز مهندسی نرم افزار برای مهندسین نرم‌افزار.
معماری نوین نرم‌افزار، تکنولوژی‌های برنامه نویسی جدید
Download Telegram
استفاده از any و unknown در TypeScript

هیچوقت در TypeScript از نوع any استفاده نکنید، اما چرا؟
چون استفاده از any به این معنی است که: «اصلا برایم مهم نیست که متغیر چه تایپی دارد» و خوب اولین دلیلی که به خاطر آن از TypeScript استفاده می‌کنیم خاصیت Type-base بودن است.

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

از ورژن 3 به بالای TypeScript، داده‌ای اضافه شده به اسم unknown
تایپ. unknown مثل تایپ any، هر مقداری را قبول می‌کند، با این تفاوت که وقتی از نوع unknown استفاده می‌کنید، تایپ اسکریپت یک Type check انجام می‌دهد و با این کار شما را مجبور می‌کند قبل از استفاده از متغیر یک چکینگ داشته باشید.
درواقع برخلاف any که می‌گوید «برای من مهم نیست که متغیر چه تایپی دارد»، unkonwn می‌گوید «مهم است تایپ متغیر چیست ولی الان تایپ را نمی‌دانم و در ادامه بررسی خواهد شد.»

برای فهم بهتر این مطلب می‌توانید این مطلب را مطالعه کنید.

⁉️ سوالات و نکات خود را در قسمت کامنت با ما در میان بگذارید.

#مریم_داودی (لینکدین)

کانال تلگرام:
@SoftwarePhilosophy

_______
👍203🔥3
Forwarded from Software Philosophy
یکی از مهمترین کارهایی که یک معمار نرم‌افزار انجام می‌‌دهد تشخیص و خلق مفهومی به نام «فضا» است. اگر در نرم‌افزاری فضاها به درستی ساخته نشوند، برنامه نویسان دچار سردرگمی می‌شوند و عمدتا کدهای تکراری خواهند نوشت. ساخت فضاهای درست توسط معمار نرم‌افزار احتمال نوشته شدن کدهای تکراری یا اضافی را کم می‌کند.

در لینک زیر مفهوم فضا در معماری نرم‌افزار توضیح داده شده
http://mehrandvd.me/2015/09/16/software-architect-its-all-about-spaces/
👍5🔥52
پرفورمنس بهتر با @Key!

پروژه Blazor ای را در نظر بگیرید که در آن لیستی از عناصر را در صفحه نمایش می‌دهیم. وقتی یکی از عناصر را ادیت یا عضو دیگری به لیست اضافه می‌کنیم، Blazor باید تصمیم بگیرد که کدام یک از عناصر قبلی حفظ می‌شوند و چگونه آبجکت مدل باید به آنها مپ شوند. به طور معمول، این فرآیند به صورت خودکار و برای رندر کلی کافی است، اما اغلب مواردی وجود دارد که کنترل فرآیند با استفاده از ویژگی دستوری @key مورد نیاز است.

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

دستور @key به Blazor اجازه می دهد تا از یک کلید خاص برای مقایسه عناصر به جای ایندکس استفاده کند Blazor آیتم‌های موجود را با موارد جدید با استفاده از مقدار کلید مقایسه می کند. به این ترتیب اضافه‌ها/اصلاحات/حذف‌ها را بهتر تشخیص می‌دهد.

@foreach (var item in items)
{
<li @key="item.Id">@item</li>
}


با استفاده از @key اگر یک نمونه از مجموعه حذف شود، فقط همان نمونه از رابط کاربری حذف می‌شود و موارد دیگر بدون تغییر باقی می‌ماند.
اگر ورودی‌های مجموعه دوباره مرتب شوند، نمونه‌های مربوطه در رابط کاربری حفظ و مرتب می‌شوند.

چه زمانی از @key استفاده نکنیم؟

به طور معمول، استفاده از @key درون یک لیست وقتی مقدار مناسب برای تعریف @key وجود دارد، منطقی است. (به عنوان مثال در یک بلاک foreach)
هنگام رندر کردن با @key هزینه عملکردی وجود دارد. هزینه عملکرد زیاد نیست، اما فقط در صورتی @key را مشخص کنید که حفظ عنصر یا جزء به نفع برنامه باشد.


برای مشاهده توضیحات کامل می‌توانید از 🔗 این لینک و 🔗 این لینک استفاده کنید.

🔗 لینک ویرگول این پست.

_____

⁉️ برای بحث و تبادل نظر فنی در مورد این پست، نظرات خود را با ما در قسمت کامنت‌ها به اشتراک بگذارید.

#نگار_قاسمی (لینکدین)

کانال تلگرام:
@SoftwarePhilosophy

_____
👍134🔥4
اعتیاد به ساخت نرم‌افزارهای جدید!

ما به عنوان مهندسین نرم‌افزار عادت کرده‌ایم که نرم‌افزار بسازیم، در حقیقت به آن معتاد شده‌ایم. به خاطر همین موضوع است که اغلب دوست نداریم به این فکر کنیم که تغییری که در نرم‌افزار می‌دهیم چطور باید در نسخه لایو اجرایی شود. خیلی وقت‌ها نرم‌افزار را به صورت بسیار عالی تغییر می‌دهیم، ولی برنامه‌ای برای اینکه این تغییر چطور باید در نسخه‌اجرایی اعمال شود نداریم.
یکی از دغدغه‌ اصلی یک مهندس نرم‌افزار خوب، تمرکز بر Software Migration است. هر قطعه کدی که توسط یک مهندس نرم‌افزار نوشته می‌شود باید با دید یک Change دیده شود که روی نسخه لایو اعمال شود، نه صرفا یک کد جدید که Create شده‌است.

http://mehrandvd.me/2015/09/06/be-a-developer-not-a-programmer/

_____

⁉️ برای بحث و تبادل نظر فنی در مورد این پست، نظرات خود را با ما در قسمت کامنت‌ها به اشتراک بگذارید.

#مهران_داودی (لینکدین - بلاگ)

کانال تلگرام:
@SoftwarePhilosophy

_____
👍7🔥32
فعال سازی Pre rendering در بلیزور

چرا باید در پروژه‌های بیلزور Pre rendering را انجام داد؟ بدون pre rendering دو مشکل در بلیزور سرور و کلاینت وجود دارد:

بلیزور کلاینت:
در این نسخه از بلیزور قبل از اینکه کاربر بتواند تعاملی با سایت داشته باشد همه‌ی content های سایت باید دانلود شود که این مورد زمان گیر است.

بلیزور سرور:
از آنجایی که ما به جاوا اسکریپت و SignalR نیاز داریم، در بهینه سازی وب سایت خود برای موتورهای جستجو مشکل خواهیم داشت. آنها اغلب یا جاوا اسکریپت را اجرا نمی‌کنند یا با WebSockets مشکل دارند.

در prerendering همه چیز رندر می‌شود و محتوای یک html استاتیک به سمت کلاینت فرستاده خواهد شد.

در نتیجه:
برای بلیزور کلاینت به این شکل خواهد بود که اطلاعات اولیه سایت به کاربر نمایش داده خواهد شد بدون اینکه نیاز باشد ابتدا مقدار زیادی دانلود انجام شود. همچنین مشکل سایت با موتورهای جستجو حل خواهد شد.

🔗 نسخه کامل این مقاله را ‌می‌توانید در اینجا مطالعه کنید.
🔗 لینک مقاله در ویرگول

___________

⁉️ برای بحث و تبادل نظر فنی در مورد این پست، نظرات خود را با ما در قسمت کامنت‌ها به اشتراک بگذارید.

#نگار_قاسمی (لینکدین)

کانال تلگرام:
@SoftwarePhilosophy

_____
🔥7👍62🎉1
تعریف مفهوم LINQ با مثال به ساده‌ترین حالت

سلام امروز می‌خواهیم در مورد LINQ بیشتر باهم بخوانیم. LINQ که مخفف Language Integrated Query است، قابلیتی مهم و قدرتمند در C# است که به برنامه‌نویسان این امکان را می‌دهد تا به صورت ساده و خوانا، داده‌های مختلف را در دسترس داشته باشند.

با استفاده از LINQ، می‌توانید داده‌های موجود در انواع مختلفی مانند آرایه‌ها، لیست‌ها، کوئری‌های SQL و ... را به صورت مستقیم و با نحوی ساده و خوانا استفاده کنید.

کاربردهای اصلی LINQ عبارتند از:
۱.جستجوی داده‌ها
۲.فیلتر کردن داده‌ها
۳.ترتیب‌بندی داده‌ها
۴.ترکیب داده‌ها
۵.پیمایش داده‌ها

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

در مقاله زیر می‌توانید مثال‌های مختلفی از LINQ را ببنید، که سعی کردم آن‌ها را با ساده‌ترین حالت ممکن توضیح بدهم :
• Filtering
• Projection
• Ordering
• Grouping
• Aggregation
• Joining
• Distinct
• Any and All
• Take and Skip

🔗 نسخه کامل این مقاله را ‌می‌توانید در اینجا مطالعه کنید.

___________

⁉️ برای بحث و تبادل نظر فنی در مورد این پست، نظرات خود را با ما در قسمت کامنت‌ها به اشتراک بگذارید.

#هوتن_همتی (لینکدین)

کانال تلگرام:
@SoftwarePhilosophy

_________
👍17🔥43🎉1
جایگاه توسعه‌دهندگان نرم‌افزار در موفقیت یا شکست سیستم‌ها

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

برای مثال سیستم‌های موفق زیادی وجود دارند که با Java و یا C# نوشته شده‌اند. همچنین سیستم‌های بی‌کیفیت زیادی نیز وجود دارد که با Java و یا C# نوشته شده‌اند. این حقیقت نشان می‌دهد دلیل موفقیت یا شکست سیستم‌ها نمی‌تواند زبان برنامه‌نویسی باشد.

مقاله زیر توضیح می‌دهد که چطور طرز فکر برنامه‌نویس‌ها موفقیت و یا شکست یک سیستم را رقم می‌زند.

http://mehrandvd.me/2015/10/15/software-quality-comes-from-people-not-languages/

_____

⁉️ برای بحث و تبادل نظر فنی در مورد این پست، نظرات خود را با ما در قسمت کامنت‌ها به اشتراک بگذارید.

#مهران_داودی (لینکدین - بلاگ)

کانال تلگرام:
@SoftwarePhilosophy

_____
👍102🔥2
چگونه تغییرات فایل‌ها را مانیتور کنیم؟

اگر بخواهیم از طریق اپلیکیشنی در دات‌نت‌ تغییرات فایل‌ها و یا فولدرها را مانیتور کنیم می‌توانیم از کلاسی به اسم FileSystemWatcher استفاده کنیم.

به طور کلی هر تغییری که شامل Creation، Deletion و یا Renaming فایل و فولدرها شود را می‌شود از طریق این کلاس مانیتور کرد.
با این کلاس می‌توانیم تغییرات فقط یک فایل خاص، و یا یک فولدر (دایرکتوری) به همراه تمام فایل‌ها و ساب دایرکتوری‌های آن فایل یا فولدر را پیگیری کنیم.

برای مثال اگر دایرکتوری به نام A داشته باشیم و داخل آن دو فایل B و C داشته باشیم، می‌توانیم به طور مجزا فقط تغییرات خود فایل B و C را نیز مانیتور کنیم، و یا به جای اینکار می‌توانیم دایرکتوری A را مانیتور کنیم. در این صورت هر تغییری که در دو فایل B و C رخ دهد قابل مانیتور کردن می‌شود.

علاوه بر این نکات، با استفاده از پراپرتی NotifyFilter این کلاس می‌توانیم تغییرات بیشتری به غیر از ایجاد شدن، حذف شدن و یا تغییر نام را پیگیری کنیم. مواردی مثل تغییر در Attributes ها، CreationTime و یا تغییراتی در سطح دسترسی و حتی تغییر سایز فایل یا فولدر و غیره ...

از محدودیت‌های این کلاس می‌توان به مورد زیر اشاره کرد:
این کلاس برای نوتیفای کردن تغییرات از بافری استفاده می‌کند که محدودیت سایز ۸ کیلوبایت دارد. بنابراین اگر تعداد تغییراتی که در یک دایرکتوری مانیتور می‌شود بیش از اندازه باشد بافر پر شده و تغییرات بعدی قابل مانیتور کردن نخواهند بود. البته سایز بافر قابل افزایش دادن است، اما هزینه بر است و توصیه نمی‌شود.

برای اینکه بدون افزایش سایز بافر دایرکتوری مورد نظر را مانیتور کنیم می‌توانیم از پراپرتی‌های این کلاس که در پایین معرفی می‌شود برای محدود کردن تغییراتی که باید توسط این کلاس مانیتور شود استفاده کنیم:

▪️ NotifyFilter
▪️ IncludeSubdirectories
▪️ Filter


🔗برای مطالعه بیشتر در مورد نحوه استفاده از این کلاس و مزایای آن می‌توانید از این لینک استفاده کنید.

___________

⁉️ برای بحث و تبادل نظر فنی در مورد این پست، نظرات خود را با ما در قسمت کامنت‌ها به اشتراک بگذارید.

#زیبا_سیفائی (لینکدین)

کانال تلگرام:
@SoftwarePhilosophy

_________
👍145🎉2🔥1🤩1
ویژگی‌هایی برای رهبری تیم

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

http://mehrandvd.me/2015/07/16/goalkeepers-vs-leaders-2/

_____

⁉️ برای بحث و تبادل نظر فنی در مورد این پست، نظرات خود را با ما در قسمت کامنت‌ها به اشتراک بگذارید.

#مهران_داودی (لینکدین - بلاگ)

کانال تلگرام:
@SoftwarePhilosophy

_____
👍62🔥2🥰1
با حواس جمع از Transient در بلیزور استفاده کنیم!

در تزریق وابستگی به شکل Transient به ازای هر درخواست دهنده‌ی جدید، یک نمونه‌ی جدید از سرویس، توسط (Dependency injection container)DI Container ساخته می‌شود و در اختیار آن قرار می‌گیرد.
وظیفه‌ی DI Container، ایجاد یک نمونه از سرویس درخواست شده، تزریق آن به کلاس درخواست دهنده و در انتها از بین بردن یا Dispose شیء ایجاد شده از سرویس ثبت شده‌است.
در مدل Transient یک نمونه را نمی‌توان به بیش از یک کلاس مصرف کننده تزریق کرد، هر نمونه تزریق شده همیشه منحصر به فرد خواهد بود.

زمانی که DI Container یک نمونه از سرویسی که به صورت Transient رجیستر شده ایجاد می‌کند، آن را فراموش می‌کند. این سرویس‌ها زمانی توسط GC جمع آوری می‌شود که سرویس‌هایی که درون آن رجیستر شده‌اند جمع آوری شوند.
برای اینکه برنامه نویسان نگران dispose کردن سرویس‌های رجیستر شده نباشند، هنگامی که کانتینر Dispose می‌شود متد Dispose همه سرویس‌هایی که IDisposable را Impelement کرده اند را Call می‌کند.

برای اینکه چنین کاری را انجام شود، وقتی نمونه‌ای از سرویسی که IDisposable را پیاده سازی کرده است را ایجاد می‌کند و رفرنسی به این سرویس را در خود نگه می‌دارد.
اشیاء Transient معمولاً زمانی برای جمع‌آوری زباله واجد شرایط هستند که شیئی که به آن تزریق شده است برای جمع‌آوری زباله واجد شرایط باشد. مگر اینکه IDisposable را پیاده سازی کرده باشد. که در این حالت رفرنسی به این نمونه در Container نگهداری می‌شود. بنابراین زمانی کاندیدای جمع آوری شدن توسط GC می‌باشد که Container توسط GC جمع آوری شود.

همچنین Container تا زمانی که کاربر برگه برنامه Blazor را نبندد توسط GC جمع آوری نخواهد شد و این به این یعنی، علاوه بر این که با هر درخواست یک نمونه از شی که به صورت Transient رجیستر شده است ایجاد می‌شود، رفرنس‌ها هم تا پایان در Container نگهداری خواهد شد و اینجاست که Memory leak رخ می‌دهد!

بنابراین اگر می‌خواهید وابستگی‌ها را به‌عنوان Transient ثبت کنید، از انجام این کار برای کلاس‌هایی که IDisposable را به طور کامل پیاده‌سازی می‌کنند اجتناب کنید.


🔗 درک این مطلب در ابتدای کار شاید سخت باشد. در این مقاله نویسنده با ذکر مثال عملی، درک این موضوع را آسان تر کرده است.
🔗 لینک مطلب در ویرگول
___________

⁉️ برای بحث و تبادل نظر فنی در مورد این پست، نظرات خود را با ما در قسمت کامنت‌ها به اشتراک بگذارید.

#نگار_قاسمی (لینکدین)

کانال تلگرام:
@SoftwarePhilosophy

________
👍112🔥1🥰1🤩1
ارتباط بین کامپوننت‌ها در بلیزور:

بهترین راه ارتباطی بین کامپوننت‌ها در بلیزور چیست؟
سه تکنیک برای انجام این کار وجود دارد:

•  EventCallbacks
•  Cascading Values
•  State Container

EventCallbacks:
این ویژگی در NET Core 3 Preview 3. به بلیزور اضافه شد. که باعث می‌شود بتوان با استفاده از Action یا Func یک کالبک برای کامپوننت‌ها  تعریف کرد. هنگامی که از EventCallback برای ارتباط بین کامپوننت‌ها استفاده شود، متد کالبک، StateHasChanged را برای رندر کردن هرگونه تغییری صدا می‌زند‌. استفاده از EventCallback برای هندل ارتباط کامپوننت‌های تو در تو بسیار خوب است.

Cascading Values:
مقادیر و پارامترهای Cascade راهی برای ارسال یک مقدار از یک کامپوننت به همه فرزندان آن کامپوننت بدون نیاز به استفاده از پارامترهای سنتی کامپوننت است.
بلیزور دارای کامپوننتی ویژه به نام CascadingValue است. این کامپوننت اجازه می‌دهد تا هر مقداری که به کامپوننت داده می‌شود، به همه فرزندانش برساند. سپس کامپوننت‌های فرزند می‌توانند به ویژگی‌های نوع Cascade شده با  [CascadingParameter] دسترسی داشته باشند.
این باعث می‌شود هنگام ساخت کنترل‌های UI که نیاز به مدیریت برخی حالت‌ها دارند، گزینه‌ای عالی باشند.

State Container:
درجات مختلفی از پیچیدگی وجود دارد که می‌توانید هنگام اجرای یک State Container به آنها بروید. بسته به اینکه به ترتیب از Blazor سمت کلاینت یا سمت سرور استفاده می‌کنید، که می‌تواند کلاسی ساده باشد که به‌عنوان سرویس Singleton تزریق می‌شود. همچنین می توانید الگوی بسیار پیچیده تری مانند Flux را پیاده سازی کنید.

این راه از ۲ راه حل دیگر پیچیده‌تر است، هرچند با این راه حل می‌توان بسیاری از کامپوننت‌ها را در کل برنامه مدیریت و هماهنگ کرد.

🔗 لینک مقاله اصلی
🔗 برای توضیحات بیشتر  لینک مقاله در ویرگول را مشاهده کنید.

___

⁉️ برای بحث و تبادل نظر فنی در مورد این پست، نظرات خود را با ما در قسمت کامنت‌ها به اشتراک بگذارید.

#نگار_قاسمی (لینکدین)

کانال تلگرام:
@SoftwarePhilosophy

________
👍9🤩21
قورباغه را دوباره اختراع نکنید!

در مهندسی نرم‌افزار، شناخت دقیق نیازمندیها و سپس ساخت محصولی مطابق این نیازمندیها یکی از کارهای به ظاهر ساده ولی در عمل پیچیده است. مطلب زیر داستانی را تشریح می‌کند که در آن یک مهندس نرم‌افزار هنگام خلقت زمین پروژه طراحی «زنبور» را بر عهده گرفته‌است. ولی به دلایلی که در داستان توضیح داده شده اقدام به طراحی یک «وزغ» می‌کند که هیچ تناسبی با نیازمندیهای «زنبور» ندارد. این مهندس نرم‌افزار در حقیقت به جای خلق موجودی که نیازمندیهای زنبور را برآورده کند، یک حیوان جدید به نام وزغ خلق کرده که اتفاقا خدا قبلا آن را با نام «قورباغه» خلق کرده بوده!

اگر لینک زیر را کامل بخوانید ارتباط آن را با پروژه‌های نرم‌افزاری می‌بینید و خواهید دید که چگونه این خطا باعث شکست یک پروژه نرم‌افزاری می‌شود.


http://mehrandvd.me/2016/03/09/reinventing-the-frog/

_____

⁉️ برای بحث و تبادل نظر فنی در مورد این پست، نظرات خود را با ما در قسمت کامنت‌ها به اشتراک بگذارید.

#مهران_داودی (لینکدین - بلاگ)

کانال تلگرام:
@SoftwarePhilosophy

_____
👍53🔥2👏1
۲۰ مارس، روزی که ChatGPT را به خواب بردند

یک تجربه بی‌نظیر! شرکت OpenAI در محصول ChatGPT باگی را پیدا می‌کند که به خاطرش سرورهایشان را خاموش می‌کنند.
مشکل این بود که من اگر پیغام جدیدی می‌نوشتم امکان داشت این پیغام در سیستم کاربر دیگری نمایش داده شود.

در ChatGPT از دیتابیس Redis استفاده شده است که عملکرد فوق‌العاده‌ای در سیستم کش دارد. برای اینکه در هر نوبت درخواست احتیاج به ارسال رکوئست به دیتابیس و لود مجدد دیتاها نباشد از این دیتابیس استفاده شده است.

حال به جای اینکه برای هر کانکشنی (برای راحتی می‌تونین هر کاری هم فرض کنید) یک Instance از شی Redis بسازند، از سیستم Redis Cluster استفاده می‌کنند که سربار خیلی کمتری را به سرورها وارد کنند.
همچنین برای برقراری ارتباط بین سرورها که پایتون است و سیستم کش دیتابیس که Redis است، از کتابخانه redis-py استفاده می‌کنند.

اما نکته جالب اینجاست که در نوشتن کدهای سمت سرور در پایتون از کتابخانه Asyncio استفاده کرده‌اند و این کتابخانه قابلیت نوشتن کدهای Async را به توسعه دهندگان می‌دهد.

این کتابخانه فضایی مشترک از کانکشن‌ها را بین سرور و کلاستر می‌سازد، که به اسم shared pool می‌شناسیمش...
با توضیحات دعوتتان می‌کنم که ادامه این تجربه ارزشمند را را مشتاقانه بخوانید.

🔗 نسخه کامل این مقاله را ‌می‌توانید در اینجا مطالعه کنید.

___________

⁉️ برای بحث و تبادل نظر فنی در مورد این پست، نظرات خود را با ما در قسمت کامنت‌ها به اشتراک بگذارید.

#هوتن_همتی (لینکدین)

کانال تلگرام:
@SoftwarePhilosophy

_______
👍126🥰1
یک .Net و این همه تایمر!

۶ کلاس مختلف تایمربرای .Net وجود دارد و هر تایمر کاربرد مخصوص خودش را دارا است.
تایمر‌های زیر مخصوص اجرای کد در thread های مخصوص UI می‌باشد.

* System.Windows.Forms.Timer
* System.Windows.Threading.DispatcherTimer

این تایمرها callback را در UI thread اجرا می‌کنند. در هر دوی این موارد وقتی در سمت UI یک ایونت Raise می‌شود، تنها یک Callback در لحظه اتفاق می‌افتد. بنابراین Thread safe می‌باشند.

تایمر دیگری که برای وب فرم‌ها وجود دارد، System.Web.UI.Timer است. این تایمر یک رویداد postback در سرور ایجاد می کند.

در نهایت سه تایمر دیگر وجود دارد که مخصوص UI نیستند:

* System.Threading.Timer
* System.Threading.PeriodicTimer
* System.Timers.Timer

ساده‌ترین و ابتدایی‌ترین نوع تایمر System.Threading.Timer است. این تایمر Callbackرا در ThreadPool برنامه ریزی می‌کند. اگر اجرای handler در زمان بیشتری نسبت به بازه زمانی مشخص شده برای اجرا طول بکشد، handler دوباره اجرا می‌شود و در نهایت با چندین handler در حال اجرا به صورت موازی مواجه خواهید شد.

تایمرSystem.Timers.Timer به صورت داخلی از System.Threading.Timer استفاده می‌کند و دارای چند ویژگی دیگر مانند AutoReset، Enabled، یا SynchronizingObject می‌باشد که امکان پیکربندی نحوه اجرای Callback ها را فراهم می‌کند. همچنین، رویداد Tick اجازه می‌دهد تا چندین handlerرا ثبت کنید. بنابراین، یک تایمر می‌تواند چندین handler را فعال کند. همچنین می‌توانید پس از راه اندازی تایمر، handler را تغییر دهید.

آخرین تایمر اضافه شده به کتابخانه‌های دات نت System.Threading.PeriodicTimer است. هدف اصلی این تایمر استفاده در حلقه‌ها و پشتیبانی از رویدادهای async است. این یک رویداد Tick ندارد، اما دارای متدی به نام WaitForNextTickAsync است. این متد یک ValueTask<bool> برمی‌گرداند که وقتی تیک بعدی آماده شد تکمیل می‌شود. مقدار bool نشان می دهد که آیا تایمر از بین رفته است یا خیر. بنابراین، می‌توانید از آن در یک حلقه while استفاده کنید. به لطف این طراحی، callback ها دچار overlap نمی‌شوند.

🔗 نسخه کامل این مقاله را ‌می‌توانید در اینجا مطالعه کنید.
🔗 لینک مقاله در ویرگول

___________

⁉️ برای بحث و تبادل نظر فنی در مورد این پست، نظرات خود را با ما در قسمت کامنت‌ها به اشتراک بگذارید.

#نگار_قاسمی (لینکدین)

کانال تلگرام:
@SoftwarePhilosophy

_____
👍19🔥43👎1
تاثیر فضا بر معماری نرم‌افزار

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

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

توضیحات کامل مفهوم فضا و تاثیر آن بر مشتری را می‌توانید در لینک زیر بخوانید.

http://mehrandvd.me/2015/10/26/spaces-shape-your-software-architecture/

⁉️ برای بحث و تبادل نظر فنی در مورد این پست، نظرات خود را با ما در قسمت کامنت‌ها به اشتراک بگذارید.

#مهران_داودی (لینکدین - بلاگ)

کانال تلگرام:
@SoftwarePhilosophy

__________
5🔥3👍2
برسی هیجان‌انگیز سرزمین EF Core Update

برای آپدیت کردن رکوردهای یک Entity روش‌ها و Method های مختلفی وجود دارد، اما کدام یک از این روش‌ها بهتر است؟ و چه تفاوتی با هم دارند؟

به طور کلی هنگام انجام عملیات آپدیت علاوه بر اینکه از چه روشی استفاده می‌کنیم، عوامل دیگری هم تاثیرگذارند مثل Indexing دیتابیس، که روی سرعت آپدیت شدن داده‌ها تاثیر می‌گذارد.

اما نکته مهم هنگام انتخاب روش آپدیت داده این است که چه تعداد داده را می‌خواهیم آپدیت کنیم. فکر کردن به این موضوع باعث می‌شود که انتخاب درست‌تری با بازدهی (Performance) بالاتری داشته باشیم.

سه روشی که می‌توانیم برای آپدیت کردن داده‌ها استفاده کنیم:

🔅EF Core Update Method
🔅Bulk Update (Bulk operation)
🔅Batch Update

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

بنابراین در تعداد داده‌های بالا، اهمیت اینکه از چه روشی برای آپدیت استفاده کنیم نمایان خواهد شد. آپدیت کردن یک رکورد از دیتابیس، با آپدیت کردن هزار رکورد یا ۱۰ هزار رکورد از دیتابیس تاثیر زیادی روی Performance سیستم دارد.
برای مثال اگر برای یک عملیات آپدیت، یک کوئری برای لود کردن داده‌ها داشته باشیم و برای هر فیلدی که آپدیت می‌کنیم یک کوئری آپدیت زده شود، بازدهی و سرعت مناسبی نخواهیم داشت.

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

🔗 نسخه کامل این مقاله را ‌می‌توانید در اینجا مطالعه کنید.

___________

⁉️ برای بحث و تبادل نظر فنی در مورد این پست، نظرات خود را با ما در قسمت کامنت‌ها به اشتراک بگذارید.

#زیبا_سیفائی (لینکدین)
#هوتن_همتی (لینکدین)

کانال تلگرام:
@SoftwarePhilosophy

_____
🔥7👍64🥰2
معماری نرم‌افزار و مشکل افزونگی کد

افزونگی کد یک اشتباه برنامه نویسی نیست، یک بیماری معماری است. مهندسین نرم‌افزار همیشه تلاش می‌کنند تا «افزونگی کد» یا کدهای تکراری را کم کنند. در بسیاری از شرایط افزونگی کد به عنوان یک بی‌دقتی برنامه‌نویس محسوب می‌شود. برنامه‌نویسانی که به «نزدیک‌بینی کد» مبتلا هستند! یعنی در کدی که می‌نویسند گم می‌شوند و یادشان می‌رود که کجای کد هستند و چرا این کد را می‌نویسند و به طور کلی نمی‌توانند دورنمایی از کاری را که انجام می‌دهند در ذهن خود تجسم کنند.

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

لینک زیر توضیح می‌دهد که چگونه یک معماری بد باعث «رشد افزونگی کد» در نرم‌افزار می‌شود.

http://mehrandvd.me/2016/02/28/growing-redundancy-an-architectural-disease/

⁉️ برای بحث و تبادل نظر فنی در مورد این پست، نظرات خود را با ما در قسمت کامنت‌ها به اشتراک بگذارید.

#مهران_داودی (لینکدین - بلاگ)

کانال تلگرام:
@SoftwarePhilosophy

__________
👍123🔥2
حفظ state قبلی کامپوننت در Angular

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

فرض کنید فرم طولانی‌ای داریم که کاربر باید فیلدهای این فرم را پر کند، اکر کاربر بعد وارد کردن بخشی از اطلاعات خود وارد صفحه دیگری شده و سپس دوباره به این بخش برگردد باید تمام اطلاعاتی که از قبل وارد کرده بود حفظ شود و نیاز به وارد کردن مجدد اطلاعات قبلی نباشد.
یا فرض کنید در کامپونتت A  یک سری داده‌ها از سرور واکشی می‌شود، با هر بار رفتن به کامپوننت B و برگشت به این کامپوننت باید به سرور ریکوست زده و داده‌ها از اول لود شوند که این روند هزینه بری است.

برای حل این مشکل به جای از بین بردن نتیجه کامپوننت فعلی موقع جابه‌جایی در بین کامپوننت‌ها می‌توانیم نتیجه کامپوننت را  ذخیره کرده و دوباره از آن استفاده کنیم. می‌توانیم این کار را با استفاده از RouteReuseStrategies انجام دهیم. این راهی است که Angular برای بهبود عملکرد در حین جابه‌جایی بین کامپوننت‌ها ارائه می‌دهد و به ‌جای از بین بردن instance کامپوننت آن را ذخیره کرده و با بازگشت به همان کامپوننت از instance ذخیره شده استفاده می‌کند.

۵ متد وجود دارد که یک به یک با ترتیب خاصی اجرا می‌شوند:

ShouldDetach
موقع جابه جایی از یک کامپوننت به کامپوننت دیگر فراخوانی می‌شود تا مشخص کند به جای از بین بردن نتیجه کامپوننت می‌توان آن را ذخیره کرد یا خیر که نتیجه را بصورت true یا false برمی‌گرداند.


Store
زمانی که ShouldDetach مقدار true برمی‌گرداند این متد فراخوانی شده و instance آن کامپوننت را ذخیره می‌کند(نحوه ذخیره سازی به ما بستگی دارد و می‌توان آن را در ابجکت، سرویس یا هرچیز دیگر ذخیره کنیم. همچنین برای دسترسی آسان‌تر می‌توانیم آن را در key-value ذخیره کنیم).


ShouldAttach
این متد خروجی true یا false برمی‌گرداند به این معنی که آیا قصد داریم از چیزی که Detach شده مجدد استفاده کنیم یا خیر، اگر بخواهیم مجدد استفاده کنیم true و در غیر این صورت false برمی‌گرداند.

Retrieve
هنگامی که ShouldAttach مقدار true برگرداند این متد فراخوانی شده و instance کامپوننتی که در متد store ذخیره کرده بودیم را برمی‌گرداند.

ShouldReusedRoute
این متد برای تعیین اینکه آیا مسیر باید دوباره استفاده شود یا خیر استفاده می‌شود.


همینطور می‌توان استفاده از RoutrReuseStrategies را سفارشی و فقط برای یک سری از کامپوننت‌های خاص نوشت، به این صورت که آرایه‌ای از stringها تعریف کرده و route کامپوننت‌هایی که قصد داریم اطلاعات آن ها را ذخیره کنیم را به آن دهیم.

‼️برای دیدن نمونه مثال و مطالعه بیشتر به لینک مراجعه کنید.


#زهرا_خانی (لینکدین)

کانال تلگرام:
@SoftwarePhilosophy

__________
👍144🔥3🤩2🥰1🎉1
پیشگیری از تولید کد بد با LINQ

همیشه هر چیز خوبی، می‌تواند بد استفاده شود و نتیجه عکس دهد. این قضیه در مورد تکنولوژی هم صادق است. مقاله زیر توضیح می‌دهد که چه عادت‌های اشتباهی هنگام کار با LINQ می‌تواند شما را به اشتباه بیندازد و باعث ایجاد کد بد شود.
یکی از خطرناک‌ترین ویژگی‌های LINQ این است که وقتی با آن کار می‌کنید احساس می‌کنید خیلی باهوشید و غالبا باعث می‌شود کد احمقانه و پیچیده‌ای با آن بنویسید. فهمیدن مفهوم Provider ها نیز مسئله مهمی است که باید با آن آشنا باشید.

مقاله زیر این نکات را شرح می‌دهد.

http://mehrandvd.me/2016/03/28/linq-the-bad-parts/

⁉️ برای بحث و تبادل نظر فنی در مورد این پست، نظرات خود را با ما در قسمت کامنت‌ها به اشتراک بگذارید.

#مهران_داودی (لینکدین - بلاگ)

کانال تلگرام:
@SoftwarePhilosophy

__________
🔥4👍2
چطور برنامه‌نویسی موازی را برای مادربزرگتان توضیح دهید!؟

برنامه نویسی موازی (Parallel Programming) و برنامه نویسی ناهمگام (Asynchronous Programming) برای اغلب برنامه‌نویسان، ممکن است جدید یا نامفهوم باشد. همه در مورد آن شنیده‌ایم ولی اغلب واضح نیست که دقیقا چیست و چرا سخت است. یک مفهوم پایه برای درک این مفاهیم پایه Thread یا نخ است. نخ‌ها مفاهیمی هستند که وظیفه انجام کارها روی CPU را دارند. در دنیای ما انسان‌ها کسانی هستند که کار انجام می‌دهند. مقاله زیر مفهوم «نخ» را به «انسان» شبیه دیده‌است و سعی کرده‌است مفاهیم پیچیده دنیای برنامه‌نویسی را با مفاهیم ساده‌ دنیای ما انسان‌ها توضیح دهد.

http://mehrandvd.me/2016/04/18/parallel-programming-grandmother/

⁉️ برای بحث و تبادل نظر فنی در مورد این پست، نظرات خود را با ما در قسمت کامنت‌ها به اشتراک بگذارید.

#مهران_داودی (لینکدین - بلاگ)

کانال تلگرام:
@SoftwarePhilosophy

__________
👍6🔥1
دیباگ راحت‌تر با DebuggerDisplayAttribute!

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

یکی از راه‌هایی که بتوانیم اطلاعات کافی مورد نیاز از یک آبجکت را در حین دیباگ به دست آوریم override کردن متد ToString کلاس است!

در این روش دو نکته وجود دارد:
۱- از آنجایی که ما متد ToString را override کرده‌ایم، باعث می‌شود Expression Evaluator تابعی را فراخوانی کند که می‌تواند باعث کند‌تر شدن دیباگ داده‌ها باشد.
۲- نمی‌توانیم داده‌های متفاوتی برای دیباگ و ToString داشته باشیم.

بنابراین، بهترین راه برای نمایش مقدار مورد نظر داده‌های شی در زمان اجرا به روشی ساده و معنی‌دار چیست؟

اتریبیوت DebuggerDisplay اینجا به کمک می‌آید.

استفاده از ویژگی DebuggerDisplayAttribute به Expression Evaluator دستور می‌دهد تا عبارت ارائه شده را ارزیابی کند و مقدار حاصل را در پنجره دیباگ نمایش دهد.

در constructor یک رشته را به عنوان ورودی قبول می‌کند و در آن رشته می‌توان هر کدام از پراپرتی‌های کلاس مورد نظر را استفاده کرد.

برای نمونه تکه کد زیر را ببینید:

[DebuggerDisplay("Name: {FirstName} - {LastName}")]
public class Customer
{
public string FirstName { get; set; }
public string LastName { get; set; }

public Customer(string firstName, string lastName)
{
FirstName = firstName;
LastName = lastName;
}
}


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

🔗 نسخه کامل این مقاله را ‌می‌توانید در اینجا مطالعه کنید.

🔗 لینک مقاله در ویرگول
_________

⁉️ برای بحث و تبادل نظر فنی در مورد این پست، نظرات خود را با ما در قسمت کامنت‌ها به اشتراک بگذارید.

#نگار_قاسمی (لینکدین)

کانال تلگرام:
@SoftwarePhilosophy

_________
👍14🔥32