Pure Coder
رفتن به کانال در Telegram
⭕️آدرس سایت: https://purecoder.ir ⭕️گروه پرسش و پاسخ: @purecoder_gp ⭕️پشتیبانی: @PureCoder_support @MohammadTaherri
نمایش بیشتر775
مشترکین
اطلاعاتی وجود ندارد24 ساعت
-17 روز
-230 روز
آرشیو پست ها
775
📛nameof
🔥بعضی مواقع یه سری constant از نوع string به شکل زیر داریم که اسم variable و محتواش یکسانه👇
public static class Roles
{
public const string Admin = "Admin";
public const string Member = "Member";
}
✅ چنین مواقعی توی سی شارپ میتونیم از nameof استفاده کنیم👇
csharp
public static class Roles
{
public const string Admin = nameof(Admin);
public const string Member = nameof(Member);
}
✅اینجوری هر موقع اسم variable رو تغییر میدی، محتواش هم خود به خود تغییر میکنه. علاوه بر اون از اشتباه های نگارشی هم در امون میمونی.
یک مثال دیگه:
public static class Roles
{
public const string Admin = "Roles.Admin";
public const string Member = "Roles.Member";
}
👇👇👇👇
public static class Roles
{
public const string Admin = $"{nameof(Roles)}.{nameof(Admin)}";
public const string Member = $"{nameof(Roles)}.{nameof(Member)}";
}
این یک مثال ساده بود. از nameof میشه برای گرفتن اسم کلاس، متد، پراپرتی و ... استفاده کرد و خیلی جاها از بروز خطا جلوگیری میکنه و با تغییر دادن اسم کلاس، متد یا پراپرتی مربوطه نیاز نیست توی کل دنبالش بگردی که ببینی کجاها از اسمش استفاده شده.
توی گزارش Exception ها، mapping هایی که برای orm مینویسم و کلی جای دیگه کاربرد داره.
@purecoder_ir775
🔥Fluent Validation
✅پکیج Fluent Validation یه پکیج محبوب توی سی شارپ هست که برای input validation استفاده میشه و امکانات زیادی داره.
🔥داشتم دنبال چنین چیزی توی دارت میگشتم که یه پکیج با اسم مشابه پیدا کردم که به طور کامل از نمونه ی سی شارپش الهام گرفته.
https://pub.dev/packages/fluent_validation
class UserValidator extends AbstractValidator<User> {
UserValidator() {
ruleFor((user) => user.age, key: 'age').isNotNull().greaterThanOrEqual(13);
ruleFor((user) => user.name, key: 'name').isNotEmpty();
}
}
// Later on
final UserValidator validator = UserValidator();
ValidationResult result = validator.validate(user);
result.errors.first.key == 'The key of the rule that errored (for example age)'
result.errors.first.message == 'The supplied error message (Passed by you, or default)'
result.errors.first.code == 'The error code'
✅یه جاهایی با نمونه ی سی شارپ متفاوته که فک میکنم بخاطر غیرفعال بودن رفلکشن توی دارت این مورد پیش اومده. ولی خب اون قدر مهم نیست.
@purecoder_ir775
🔥وقتی که unit test میزنیم یکی از نکات مهم اینه که تست ها مرتب اجرا بشن. یعنی با هر تغییر کوچولوی کد بهتره که تست ها اجرا بشن.
😭حالا فرض کن این کار رو به صورت دستی بخوای انجام بدی و با هر تغییر کد بری و یه بار تست ها رو اجرا کنی و مثل کبک زل بزنی به صفحه تا تست ها اجرا بشن و نتیجه رو ببینی و کار رو ادامه بدی...
⏰اینکار انقدر زمان بر میشه که بعد یه مدتی قید اجرا کردن مداوم تست ها رو میزنی و در نتیجه اون فایده ای که باید از تست بگیری رو نمیگیری.
اینجا پای ابزار میاد وسط که کارهای تکراری رو انجام بده. انسان برای انجام کارهای تکراری ساخته نشده!!!
یه ابزاری که توی پس زمینه بشینه و با هر تغییر کد،خودش تشخیص بده که چه تست هایی رو باید اجرا کنه و تست های مربوطه رو اجرا کنه.
اینجوری هم حواس تو پرت نمیشه و هم سرعت اجرا شدن بالا میره، چون تست ها رو هوشمند اجرا میکنه.
✅.NET - Ncrunch
توسط jet brains برای دات نت توسعه داده شده و توی ویژوال استدیو و رایدر قابل استفادست.
✅JAVA - Infinitest
ابزاری که جاوا کار ها میتونن استفاذه کنن. توی Eclipse & IntelliJ.
راه های دیگه هم هست ولی ظاهرن نزدیکترین به ncrunch همینه.
کاتلین کار ها هم میتونن ازش استفاده کنن.
✅JS - Wallaby.js
جی اس کار ها هم میتونن همین نتیجه رو برای کدهای جاوااسکریپ و تایپ اسکریپت خودشون با این ابزار بگیرن.
بازم راه های دیگه هم هست ولی نزدیکترین به ncrunch اینه!!!
این هم روی vs code و web storm پشتیبانی میشه.
❌Dart
متأسفانه برای دارت و فلاتر راه حل مناسبی در حال حاضر وجود نداره یا دست کم من نمیدونم.
پ.ن: من ابزارهای جاوا و جی اس رو استفاده نکردم و فقط معرفی کننده بودم. راه های دیگه و شاید بهتری هم برای این پلتفرم ها وجود داشته باشه.
نکته ی مهم اینه که خودمون دستی تست ها رو اجرا نکنیم و یه ابزاری باشه که با هر تغییر کد این کار رو انجام بده و خیلی هم بهینه انجامش بده تا فرایند کد نویسی و ریفکتور کردن رو مختل نکنه. خود ابزاره مهم نیست. این کارو انجام بده، هر چی میخواد باشه.
@purecoder_ir
775
🔥سطح مهندس های نرم افزار ایران از نگاه کسی که توی گوگل بوده و سال ها خارج از ایران بوده.
😱کسایی که میگن توی ایران سطح فنی همه پایینه و مرغ خارجیا غازه، مشکل از خودشونه!!!
❓خودمون چه قدمی برای بهبود برداشتیم؟
پ.ن: من این فرد رو نمیشناسم و به صحبت هاش استناد نمیکنم. ولی حرفی که میزنه رو قبول دارم و اصلن قبول ندارم که توی ایران سطح فنی افتضاحه و پات رو که از ایران بیرون بگذاری، سطح فنی و عمق دانش سر به فلک میگذاره. برعکس یه موقع هایی با افرادی روبرو میشی که مغزت سوت میکشه و تعدادشون هم کم نیست.
@purecoder_ir
775
🔥Configurations in .NET
توی دات نت میتونیم تنظیمات برنامه رو توی سطوح مختلف به برنامه پاس بدیم.
1️⃣appsettings.json
2️⃣appsettings.[Environment].json
👉appsettings.Development.json
👉appsettings.Production.json
3️⃣OS Environment variables
4️⃣Command Line Args
1️⃣پایین ترین سطح appsettings.json هست.
2️⃣بعد از اون تنظیمات مربوط به environment خاص هست. مثل
👉appsettings.Development.json
👉appsettings.Production.json
تنطیماتی که اینجا قرار میگیرن, تنظیمات appsettings.json رو در صورت تداخل اوراید میکنن.
3️⃣سطح بعدی قرار دادن تنظیمات توی environment variable های سیستم عامل هست که این ها هم تنظیمات دو سطح قبلی رو در صورت تداخل اوراید میکنن.
اینجا میتونیم تظیمات رو با استفاده از env var هایی که روی سیستم عامل یا داکر کانتینر ست میکنیم اعمال کنیم.
4️⃣اخری هم command line args هست که نسبت به همه اولویت بالاتری داره.
✅پس برای مثال اگه یه connection string رو توی appsettings گذاشته باشی و توی development ازش استفاده کنی, توی پروداکشن میتونی با env var ای که روی داکر ست میکنی اورایدش کنی.
پ.ن: این اولویت بندی و اوراید کردن توسط فریمورک انجام میشه و لازم نیست ما کاری انجام بدیم.
توی برنامه ما با استفاده از configuration کانفیک مربوطه رو میگیرم و استفاده میکنیم و همه ی کارهای مربوط به اولویت بندی و اوراید شدن توسط فریمورک انجام میشه.
Configuration["ConnectionString:Default"]
🔥فرمت کانفیگ هایی که توی appsettings.json قرار میگیرن به صورت json هست:
{
"ConnectionString": {
"Default ": "...."
}
}
ولی موقع تنظیم کردن توی environment variable باید به این صورت عمل کنیم:
expose ConnectionString__Default = "..." // linux
setx ConnectionString__Default "..." //windows
اون __ کار nested object توی json رو میکنه!!!
توی داکر هم باید با همین فرمت تعریف بشن (__)
@purecoder_ir
775
برنامه نویس ها علاقه ی زیادی به reuse کردن کد دارن.
این علاقه باعث میشه که خیلی وقت ها دنبال این باشن که چند تا مفهوم (concept) رو generalize کنن و ازش یه base class تولید کنن که یه کدی رو به اشتراک میگذاره و بقیه کلاس ها ازش ارث بری میکنن ... .
خیلی وقت ها خیلی عجله میکنن و قبل از اینکه خود اون concept ها رو implement کرده باشن میخوان به زور ازش یه base class در بیارن. یعنی اول base class تولید میشه و بعد ... .
این عجله بیشتر وقت ها نتیجه ی خوبی نداره.
ابتدا باید هر concept به صورت جداگانه پیاده سازی بشه. صبر و تحمل به خرج بدیم و اجازه بدیم و اجازه بدیم و اجازه بدیم که اگه duplication واقعی بوجود اومد، اون موقع از قوه ی generilazation خودمون استفاده کنیم و یه base class استخراج کنیم.
ریفکتورینگ ابداع شده تا بتونیم صبور باشیم و هر کاری رو به موقع انجام بدیم و نه زودتر از موعدش.
@purecoder_ir
775
چیزی که برای TDD بیشتر مواقع گفته میشه، چرخه ی Red Green Refactor هست، در حالیکه این چرخه بخشی از TDD هست.
قبل از شروع حل مساله یه کوچولو در مورد مساله فکر میکنیم و یه تعداد test به ذهنمون میرسه.
چون که همه ی اون ها رو یهویی نمیتونیم بنویسیم و باید دونه دونه و قدم به قدم جلو بریم، عنوان این تست ها رو به صورت خیلی خلاصه (جوری که وقت نگیره) روی یه کاغذ (یا هر جای دیگه) مینویسیم.
بعد که شروع کردیم به حل مساله اسونترین تست رو از توی اون لیست انتخاب میکنیم و چرخه ی Red Green Refactor رو براش اعمال میکنیم. بعد از پاس شدن تست اون رو از توی لیست خط میزنیم. و همین روند رو ادامه میدیم و با پاس شدن هر تست، از لیست خطش میزنیم و اسونترین تست رو دوباره از توی اون لیست برمیداریم و پیاده میکنیم.
در حین implement کردن مساله و در حین پیاده سازی یه تست ممکنه چیزای جدیدی از مساله یاد بگیریم و تست های جدیدی به ذهنمون برسه.
اینجا برای اینکه ذهنمون اشفته نشه و چون نمیشه به ذهن اعتماد کرد، تستی که به ذهنمون رسیده رو به ته اون لیست (روی کاغذ) اضافه میکنیم و کارمون رو ادامه میدیم.
تست هایی که روی کاغذ نوشته شدن نباید به ترتیب پیاده بشن، بلکه باید توی هر مرحله اسونترین اون ها رو انتخاب کنیم و پیاده کنیم و خط خطی کنیم.
پ.ن: اگه مساله انقدری برات سادست، میتونی کاغذ رو حذف کنی و اون بخش رو ذهنی انجام بدی. ولی برای مساله های سخت حتمن کاغذ یا یه چرک نویس فیزیکی با هر عنوانی استفاده کن.
@purecoder_ir
775
خب جمعه ها پست های غیر برنامه نویسی میگذارم😍😜
🌞یکم با نام های قشنگ فارسی بیشتر اشنا بشیم.
🌞خراسان = خورشیدگاه ایران
🔥اسمی که در زمان ساسانی انتخاب شده.
✅خراسان = خور آیان
✅خور = خورشید
✅در زبان پهلوی به آید میگفتن آسد.
🌞خوراسان یعنی جایی که از اونجا خورشید وارد قلمرو ایران میشده. (و البته هم اکنون هم همین طور)
خراسان اون موقع شامل خراسان امروزی، ترکمنستان، ازبکستان و ... بوده.
پ.ن: زبان پهلوی یا فارسی میانه خواستگاه زبان فارسی امروزیست.
زبان پهلوی هر کو شناسد خور آسان یعنی انجا کو خور آسد خور آسان رو بود معنی خور آیان کجا کز وی خور آید سمت ایرانشعر از فخر الدین اسعد گرگانی منبع: https://www.instagram.com/sadrafr?igsh=cHF4NHFxb2g0cTZm
@purecoder_ir
775
قبل از Git سورس کنترل های مهم مثل subversion بر اساس ایده ی central repository کار میکردن. یه ریپوزیتوری مرکزی بود که همه بهش وصل میشدن.
ولی گیت ایده ی Distributed Source Control رو مطرح کرد.
یعنی قبلن اگه ۱۰۰ نفر روی یک پروژه کار میکردن، یه ریپوزیتوری مرکزی روی cloud بود که همه باید بهش متصل میشدن و روش کار میکردن و اون ریپو بود که نسخه ی معتبر پروژه بود.
قبل از subversion حتا cloud هم خیلی مطرح نبود.
ولی توی دنیای گیت اگه ۱۰۰ نفر روی یک پروژه کار کنن، همشون یه نسخه ی لوکال یا محلی برای خودشون دارن و همه ی این نسخه ها هم نسخه های معتبر پروژه هستن. درسته که یه ریپوزیتوری روی cloud هست. ولی این ریپو کمک میکنه که نسخه های لوکال به طور پیوسته باهم سینک یا همگام یشن. این به این معنی نیست که اون ریپویی که روی cloud هست از درجه ی اعتبار بالاتری نسبت به نسخه ی لوکال برخورداره. تمام نسخه هایی که توی تمام ماشین ها اجرا میشن از یک درجه ی اعتبار برخوردارن.
و این میشه ایده ی Distributed Source Control.
@purecoder_ir
775
تصور اینکه ۶۰ سال پیش کدها شون رو روی یه سری punched card هک میکردن و هر پروژه ای شامل یه عالمه از این punched card ها بوده و سورس کد یه پروژه رو (ینی این کارت ها رو) توی کابینت یا کشو نگه میداشتن، و در کمتر از ۶۰ سال به این نقطه رسیدیم خیلی سخته.
(هر کارت یه خط برنامه رو در برمیگرفته و هر برنامه شامل تعداد خیلی زیادی از این کارت ها بوده که با یه دونه کش به هم میبستنشون تا گم و گور نشن.🤣 یعنی برنامت از نظر فیزیکی وزن زیادی داشته و برای حملش باید یه کامیون میگرفتی😂 )
فرض کن این کارت ها که هر کدوم شامل یه خط برنامه بودن از دستت ول میشدن و ترتیب کدها به هم میریخت.😂😂🤦♂🤦♂
پس در اینده هم دنیای نرم افزار به گونه ای پیش میره که کارهایی که الان میکنیم، پیش پا افتاده یا حتا خنده دار تلقی میشه.
جهان نرم افزار ترسناکه!!!
@purecoder_ir
775
استفاده از واژه های انگلیسی در گفت و گو های روزمره وقتی که معادل فارسی زیبا داره، خیلی زشته. متاسفانه این زشتی گریبان بیشتر ماها رو گرفته...
@purecoder_ir
775
Repost from N/a
ویراش دوم کتاب Clean Code.
باب مارتین، ۲۰۲۵.
🔥تغییرات زیادی نسبت به ویرایش اول داشته:
✅از اصول low level کلین کد،
✅تا اصول سالید و،
✅اصول طراحی component ها،
✅معماری کلین،
✅تست،
✅و حتا هوش مصنوعی،
توی این ویرایش صحبت شده.
البته خیلی از این موارد توی ویرایش اول هم بود. ولی خب یه باز طراحی شده.
@purecoder_ir
775
🔥دارت جدید
// Use dot shorthand syntax on enums:
enum Status { none, running, stopped, paused }
Status currentStatus = .running; // Instead of Status.running
// Use dot shorthand syntax on a static method:
int port = .parse('8080'); // Instead of int.parse('8080')
class Point {
final double x, y;
const Point(this.x, this.y);
const Point.origin() : x = 0, y = 0; // Named constructor
// Factory constructor
factory Point.fromList(List<double> list) {
return Point(list[0], list[1]);
}
}
// Use dot shorthand syntax on a named constructor:
Point origin = .origin(); // Instead of Point.origin()
// Use dot shorthand syntax on a factory constructor:
Point p1 = .fromList([1.0, 2.0]); // Instead of Point.fromList([1.0, 2.0])
// Use dot shorthand syntax on a generic class constructor:
List<int> intList = .filled(5, 0); // Instead of List.filled(5, 0)
🙅♂من نظر خوبی در مورد این ویژگی ندارم.
@purecoder_ir
775
آیا اصل Dependency Inversion توی زبان های داینامیک تایپ که چیزی به اسم اینترفیس ندارن هم مطرحه یا این اصل فقط یه مساله مربوط به زبان های استاتیک هست؟
775
به طور کلی دامنه ی تغییرات توی کدوم یک از لایه های زیر بیشتره؟(کوییز نیست، نظر و تحلیل خودت رو بگو)
775
❓دیتابیس ها معمولن از چه دیتااستراکچر هایی برای ذخیره ی index ها استفاده میکنن تا بعدن کوئری ها روی اون index ها بهینه تر بشن؟
✅یکی از مهمترین دیتااستراکچر هایی که استفاده میکنن Tree ها هستن.
@purecoder_ir
775
دیشب یه دیاگرام به صورت عکس میخاستم که چت جی پی تی بهم بده، فک کنم ۴ ساعت منو الاف کرد و همش میگفت سیستم تولید تصویرم خراب شده😂😂
اخرش باهاش دعوام شد و افتاد به عذرخواهی کردن😂
بعدش بهش گفتم اگه میخوای ببخشمت یه نسخه پلاس رایگان بهم بده🥲
همون موقع و در کمتر از یک ثانیه عکس رو تولید کرد و بهم داد 😂
سیستم تولید تصویرش سریع درست شد😂
