یوشا

دست نوشته ها و تجربیات شخصی

یوشا

دست نوشته ها و تجربیات شخصی

شهید دکتر مصطفی چمران: می گویند تقوا از تخصص لازمتر است، آنرا می پذیرم، اما می گویم آنکس که تخصص ندارد و کاری را می پذیرد بی تقواست!

طبقه بندی موضوعی
تبلیغات
Blog.ir بلاگ، رسانه متخصصین و اهل قلم، استفاده آسان از امکانات وبلاگ نویسی حرفه‌ای، در محیطی نوین، امن و پایدار bayanbox.ir صندوق بیان - تجربه‌ای متفاوت در نشر و نگهداری فایل‌ها، ۳ گیگا بایت فضای پیشرفته رایگان Bayan.ir - بیان، پیشرو در فناوری‌های فضای مجازی ایران

1- حتی الامکان دایرکتیوهای using رو بداخل namespace منتقل کنید و در خارج از محدوده namespace رها نکنید.

StyleCop: SA1200: UsingDirectivesMustBePlacedWithinNamespace

namespace ConsoleApp1
{
   using System;
   using System.Collections.Generic;
   using System.Text;

   class Program
   {
      private static void Main(string[] args)
      {
      }
   }
}

نکته: درصورتیکه فقط یک namespace در فایل موردنظر موجود باشه.

 

2- همیشه reference های بلااستفاده رو از پروژه حذف کنید.

نکته: البته هنگام کامپایل برنامه، همه reference های استفاده نشده حذف میشن، ولی خب همیشه محیط کدنویسی رو تمیز و خلوت نگه دارید.

 

3- همیشه دایرکتیوهای using بلااستفاده(خاکستری رنگ) رو از کلاسها حذف کنید.

   using System.Drawing;
   using System.Resources; // <-----
   using System.Reflection; // <-----
   using System.Runtime.InteropServices; // <-----
   using System;
   using System.Windows.Forms;

 

4- جهت بازگشت چندین مقدار از یک متد میتونید از کلمه کلیدی ref یا out یا پرانتز (type1, type2, typeN) یا حتی Tuple استفاده کنید:

public Tuple <int, string, string> GetStudent()
{
   int studentId = 11;
   string firstName = "Alex";
   string lastName = "Koertson";
   return Tuple.Create(studentId, firstName, lastName);
}

نکته: Tuple از نوع reference type هستش و حداکثر ظرفیت 8 عنصر رو داره. همچنین از دات نت نسخه 4 و جدیدتر در دسترسه.

 

5- قابلیت های مخفی در #C!

6- جهت نادیده گرفتن escapce character ها در رشته یا رفع خطای Unrecognized escape sequence می تونید از علامت @ در ابتدای شروع رشته استفاده کنید:

myStr = @"\\MyServer\TestFolder\NewFolder";

 

7- برای بدست اوردن مسیر جاری برنامه های WinForm، بهتره از Application.StartupPath استفاده کنید و برای برنامه های Console بهتره از Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) استفاده کنید.

توجه: دستور Directory.GetCurrentDirectory و AppDomain.CurrentDomain.BaseDirectory و Environment.CurrentDirectory به دلایل زیادی میتونن تغییر کنن و مسیر متفاوتی به شما بدن، همچنین دستور Path.GetDirectoryName(Environment.GetCommandLineArgs()[0]) در بعضی موارد نام و مسیر برنامه رو برگشت نمیده. پس برای بدست اوردن مسیرهای ثابت قابل اطمینان نیستن.

 

8- اگر از resources و settings در پروژه تون استفاده نمی کنید بهتره اونها رو حذف کنید:

 

 

9- درصورتیکه از قابلیت های غیر Common Language Specification / CLS در کدهاتون استفاده نمی کنید، خاصیت CLSCompliant رو به فایل AssemblyInfo اضافه کنید:

[assembly: CLSCompliant(true)]

 

10- همیشه از language keywords(مثل int, string, float) بجای base class type(مثل Int32, String, Single) استفاده کنید.

 

11- جدول سازگاری بین نسخه های مختلف .Net:

 

12- چک لیست ساخت کلاس Utility:

1- کلاس باید static باشد.

نکته: با اینکار کلاس بطور غیرصریح abstract و sealed خواهد بود. بنابراین عمل Inheritance و Instantiation صورت نخواهد گرفت. همچنین constructor و default constructor نخواهد داشت.

2- کلاس باید از شی Object ارث برده باشد.

3- همه اعضای کلاس باید static باشند.

 

13- آیا میدونید interpolation رشته در هنگام compile برنامه به String.Format تبدیل میشه؟

یعنی کد:

string a = "Hello";
string b = $"{a} world";

بعد از compile برنامه تبدیل میشه به کد:

string a = "Hello";
string b = string.Format("{0} world", a);

 

14- نتیجه مقایسه سرعت پردازش رشته توسط String.Format و StringBuilder و +

کندترین String.Format و سریعترین StringBuilder

 

15- نکته جزیی: آیا میدونید exception های هندل/catch نشده بصورت خودکار به خروجی STDERR فرستاده میشن؟

 

16- تنها زمانی باید از کلاس ResourceManager استفاده کنید که قراره Resouce از نوع External رو داخل برنامه لود کنید.

 

17- سعی کنید همیشه تاریخ و زمان رو بر اساس UTC در فایل و دیتابیس ذخیره کنید و نه زمان محلی.

https://stackoverflow.com/questions/11537106/is-it-always-a-good-idea-to-store-time-in-utc-or-is-this-the-case-where-storing

https://stackoverflow.com/questions/2532729/daylight-saving-time-and-time-zone-best-practices

https://stackoverflow.com/questions/5666836/date-time-conversion-from-users-local-time-to-utc-on-website/5667869#5667869

https://stackoverflow.com/questions/2580478/storing-date-times-as-utc-in-database

و برای خوانایی و تبدیل بهتر میتونید از فرمت استاندارد ISO-8601 استفاده کنید. DateTime.UtcNow.ToString("o", CultureInfo.InvariantCulture);

 

18- نکته جزیی: فراموش نکنید که داده نوع NULL همیشه یک مقدار Invalid/نامعتبر هستش و هرچیزی بجز NULL یک مقدار Valid/معتبر هستش، حتی ""

 

19- تحت هیچ شرایطی مقدار NULL رو return نکنید. درعوض رشته خالی "" یا 0 یا آرایه خالی [] بازگشت بدید.

 

20- هرگز از اعداد منفی برای تعیین Status/Exit code استفاده نکنید. از انجاییکه برای سیستم هر چیزی جز عدد 0 به FALSE ترجمه میشه و بسیاری از زبانها قابلیت return کردن اعداد منفی برای Status/Exit code رو ندارن، بهترین مقدار اعداد 0 یا مثبت هستن.

 

21- جدول تفاوت انواع Timer:

  System.Windows.Forms System.Timers System.Threading
Timer event runs on what thread? UI thread UI or worker thread Worker thread
Instances are thread safe? No Yes No
Familiar/intuitive object model? Yes Yes No
Requires Windows Forms? Yes No No
Metronome-quality beat? No Yes* Yes*
Timer event supports state object? No No Yes
Initial timer event can be scheduled? No No Yes
Class supports inheritance? Yes Yes No

(C) MSDN Magazine

 

22- نکته جزیی: در دنیای .Net واژه Entity درواقع همون Model یا POCO هستش که به یک Table در دنیای database اشاره داره.

 

23- مزایای استفاده از dependency injection در طراحی کلاس/متد:

  • تمیز شدن کد و افزایش خوانایی کد
  • آزاد شدن اتصالات و روابط کلاسها(loosely coupled)
  • افزایش reusable شدن کد
  • ساده شدن فرایند test کد

 

24- نکاتی راجب الگوهای طراحی DAO و Repository:

هردو object-oriented هستن

هردو زیر مجموعه Integration Tier Design Pattern هستن

هردو در لایه DAL یا persistence layer قرار دارن و برای پیاده سازی این لایه ها استفاده میشن

هردو میتونن Object یا دسته ای از Objects رو return کنن

هردو میتونن برای دور نگه داشتن application از تکنولوژی زیرساختی data source استفاده بشن(در واقع یک  uniform data access API)

DAO به data source نزدیکتره اما Repository به application نزدیکتره

از DAO بیشتر برای دسترسی به Entities استفاده میشه و از Repository بیشتر برای سرهم کردن چند کلاس/خروجی DAO

از DAO برای مخفی سازی مباحث سطح پایین data source و پیچیدگی ها استفاده میشه

DAO معمولاً به data source vendor خاصی وابسته نیست

DAO معمولاً table محور هست اما Repository معمولاً Object محور


25- کاربردها و اهداف بلوک های static:

- برای initialize کردن کدهای استاتیک(static) که هنگام Load شدن کلاس اعمال بشن

internal static Dictionary<String, String> myField = new Dictionary<String, String>();

static
{
   myField.Add("Test name", "Test value");
   // ...
}

- برای initialize کردن کلاسهای master

public class MasterClass
{
   static
   {
      SlaveClass.initialize();
      // ...
   }
}

توجه: باید فیلدهای static در بلوک static قرار بگیرند و initialize بشن و نه در constructor! اینها بخشی از class definition هستن و نه object.


26- سعی کنید متغیرهای کلاس رو در خارج از متد constructor آماده سازی/Initialize کنید. (اینها مقادیر پیشفرض دارن و حتی قبل از اینکه سازنده کلاس صدا زده بشه مقدار دهی می شوند. پس دوباره به اونها مقدار ندید. بعلاه خوانایی کلاس راحت تر و سریع تر انجام میشه)

 

27- همیشه هنگام توسعه نرم افزار، exception ها و خطاها رو (در یک متغیر یا فایل) log کنید و توسط فرمی (با اجازه کاربر!) برای سرور/گیرنده خودتون ارسال کنید.

با اینکار یک سیستم bug report مناسب رو پیاده سازی کردید که بسیار به رفع اشکالات و بهبود برنامه تون کمک خواهد کرد.

 

28- هرگز بدون اجازه کابر، برنامه رو update نکنید.

 

29- هرگز بدون آگاهسازی کابر، اطلاعات اینترنتی رو دریافت و ارسال نکنید.

 

30- حتی الامکان از فراخوانی و کار با کلاس اشیا بصورت مستقیم در داخل حلقه ها خودداری کنید.

سعی کنید اونها رو به متغیرها انتقال بدید و بعد متغیر رو وارد حلقه کنید.

 

31- اصول طراحی کلاس:

- همیشه داده ها و فیلدها رو private نگهدارید و از اصول encapsulation پیروی کنید.

- همیشه فیلدها رو initialize کنید.

- هرکلاس رو به یک نوع/دسته از داده اختصاص بدید.

- کلاسهای چند منظوره با چند مسئولیت طراحی نکنید، بلکه آنها را تجزیه و جداسازی کنید.

- بی دلیل برای همه فیلدها و داده ها accessor و mutator طراحی نکنید. (set/get)

- همیشه بهترین و مناسبترین نام رو برای کلاس و متد تعیین کنید تا هدف رو بخوبی انعکاس بدهند.

- حتاالمکان کلاسها رو immutable (غیرقابل تغییر) طراحی کنید.

- بجای استفاده مکرر تودرتو if/else switch foreach از interface یا کلاس abstract استفاده کنید.

- حتاالمکان کلاس رو static طراحی نکنید. (بخاطر global state و مشکلات unit testing)

- از نوشتن متدهای طولانی و سنگین خودداری کنید. معمولاً متدهای طویل نشاندهنده رفتار و وظایف متعدد هستش که نیاز به تجزیه و refactoring داره.

- از قانون DRY (مخفف Don’t Repeat Yourself) پیروی کنید... متدهای تکراری رو با ساخت superclass abstract یکی کنید.

 

32- همیشه تصاویر PNG پروژه رو توسط برنامه Image Tuner یا OptiPNG یا PNGCrush بهینه سازی کنید.

این برنامه ها قادرند header ها و metadata اضافی داخل فایل تصویر رو حذف و تصویر رو compress کنند.

https://github.com/imagemin/imagemin-cli

https://imageoptim.com/versions

https://pngquant.org

https://pmt.sourceforge.io/pngcrush/

https://lcdf.org/gifsicle

https://github.com/svg/svgo

https://trimage.org

https://images.guide

https://github.com/svg/svgo

(Thanks to Elsa Ferreira )

https://websiteplanet.com/webtools/imagecompressor/

Mac OS:

https://github.com/ImageOptim/ImageOptim 

https://nukesaq88.github.io/Pngyu/

https://pngquant.org/pngquant.tar.bz2

 

33- بجای استفاده از تصویر سیاه از رنگ سیاه #000000 استفاده کنید. بجای استفاده از تصویر سفید از رنگ سفید #FFFFFF استفاده کنید و امثالش...

 

34- حتی الامکان بصورت مستقیم/directly فیلد های داخل اشیا رو فراخوانی کنید، بجای استفاده از پراپرتی و setter/getter.

زمانی باید از setter/getter استفاده بشه که قراره عملیاتی بر روی فیلد مورد نظر انجام بشه.

 

35- مهمترین تفاوت الگوی Adapter و الگوی Facade:

الگوی Adapter عمل تبدیل(convert) کلاس انجام میده اما الگوی Facade عمل ساده/خلاصه سازی(simplify) کلاس انجام میده.

- الگوی Adapter در نهایت یک کلاس رو پوشش میده اما الگوی Facade چندین کلاس رو پوشش میده.

 

36- نکته جزیی: پیشنهاد می کنم از تگ @todo در XML doc comment استفاده نکنید... از انجایی که مستندات کدها عمومی هستند و برای کسب اطلاعات کلی طراحی شدند، محل مناسبی برای قرار دادن TODO های پروژه نیستند.

 

37- نکته جزیی: همیشه در آخر هر فایل یک خط خالی(blank line) قرار بدید. بعضی از ویرایشگر ها بجای بررسی EOF، خط آخر رو ignore می کنند. (در همه زبانها)

 

38- آیا میدونید Constructor ها متد نیستند و فقط class type رو بازگشت میدن؟

class Vehicle
{
    public Vehicle() // Constructor
    {

    }

    public void vehicle() // Method!
    {
        // print 123
    }
}

Vehicle Saloons = new Vehicle(); // Construct
Saloons.vehicle(); // Method call

حتی درصورت عدم وجود Constructor، کامپایلر یک Constructor بدون پارامتر، همنام کلاس شما تولید میکنه...

 

39- یادتون باشه که تنها دلیل استفاده از ابزارهای اتوماسیون build(مثل MSBuild, NAnt, Cake, Ant) فقط کاهش خطاهای انسانی و صرفه جویی در زمان هستش.

 

40- توسط ابزار nukeeper یا dotnet-outdated می تونید بصورت خودکار پکیج های NuGet پروژه یا سیستم رو بروزرسانی کنید.
 

۹۹/۱۲/۱۵

نظرات (۰)

هیچ نظری هنوز ثبت نشده است
کاربران بیان میتوانند بدون نیاز به تأیید، نظرات خود را ارسال کنند.
اگر قبلا در بیان ثبت نام کرده اید لطفا ابتدا وارد شوید، در غیر این صورت می توانید ثبت نام کنید.
شما میتوانید از این تگهای html استفاده کنید:
<b> یا <strong>، <em> یا <i>، <u>، <strike> یا <s>، <sup>، <sub>، <blockquote>، <code>، <pre>، <hr>، <br>، <p>، <a href="" title="">، <span style="">، <div align="">