نمایش نتایج 1 تا 13 از 13

نام تاپیک: چند نکته برای برنامه نویسی بهتر در #C

  1. #1
    کاربر دائمی
    تاریخ عضویت
    بهمن 1382
    محل زندگی
    فعلا ایران - فعلا تهران
    پست
    2,628

    چند نکته برای برنامه نویسی بهتر در #C

    نویسنده :‌داریوش تصدیقی

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

    - مسوولین مایکروسافت تاکید دارند در صورتیکه تداخلی (Conflict) در بکارگیری کلاس ها وجود نداشته باشد، همیشه فضاهای نامی (Namespace) را در بالای صفحات، با استفاده از کلمه Using مشخص نماییم. البته این گفته تا حدودی نیز صحیح می باشد و شاید اکثر دوستان نیز این قاعده را رعایت کرده و می کنند و اکثرا در بالای صفحات خود با عباراتی مانند نمونه های ذیل برخورد کرده اند:


    Using System;
    Using System.Windows.Forms;

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

    - شاید خیلی از دوستان، قبل از برنامه نویسی با زبان های شیء گرا خصوصا #C با زبان های برنامه نویسی Structured مانند Foxpro و یا Event Oriented مانند Visual Basic و غیره آشنایی داشته باشند. در آن زبانها بسیار اتفاق افتاده است که برنامه نویسان تمایل داشته باشند تا قسمت هایی از سورس کد خود را در داخل یک زیر برنامه (Sub Routine) نوشته و در مکانهای مناسبی صدا (Call) نمایند. این تفکر کماکان با حفظ احتیاط در زبان های برنامه نویسی شیء گرا نیز قابل پیاده سازی می باشد. تعجب نکنید! تصور نکنید که برای هر کاری در زبانهای برنامه نویسی شیء گرا باید کلاسی خلق کرده و از آن شیئی ایجاد کرده تا بتوانید تابعی (متدی) از آنرا اجرا نمایید!. در زبان برنامه نویسی #C، شما می توانید کلاسی ایجاد کرده و در آن متد و یا متدهایی به صورت استاتیک (Static) تعریف نمایید. متدهای استاتیک مربوط به خود کلاس بوده و اساسا ارتباطی با اشیاء کلاس ندارند. لذا شما می توانید از طریق خود کلاس، تابع استاتیک مربوطه را اجرا نمایید. در صورتی که با Console Application کار کرده باشید، به کرات با دستوراتی به شکل ذیل مواجه شده اید:

    System.Console.WriteLine("Hello World!");

    در نمونه فوق، در فضای نامی System، کلاسی به نام Console وجود دارد که در داخل آن تابع استاتیکی به نام WriteLine در نظر گرفته شده است. در نمونه فوق شما نیازی به ایجاد شیئی از نوع کلاس Console برای به اجرا درآوردن تابع WriteLine ندارید!

    با توجه به مطالب فوق، شاید در یک پروژه واقعی ایجاد توابعی که چندان ارتباطی با مفهوم کلاس و شیء و غیره ندارند، بسیار ضروری باشد. ما اینگونه پیشنهاد می کنیم:

    معمولا بهتر است که در هر پروژه یک کلاس با نام Globals و یا Publics و یا Utilities به شکل ذیل تعریف نمایید:

    public sealed class Utilities
    {
    private Utilities(){}
    }


    و سپس تمامی توابعی که تمایل دارید به طور کاملا مستقل اجرا شوند را به صورت استاتیک در داخل آن تعریف نمایید:

    public sealed class Utilities
    {
    private Utilities(){}

    public static bool CreateFolder(string pathName)
    {
    bool blnResult = true;

    return(blnResult);
    }
    }

    در تکمیل مطالب فوق، عنوان چند نکته ضروری می باشد:

    اول آنکه در تعریف این کلاس، از کلمه sealed استفاده شده است. بکارگیری این کلمه بدین معنی است که از این کلاس نمی توان Inherit کرد، که بدیهی است ارث بری از چنین کلاسی که تنها با یک سری توابع استاتیک تعریف شده است، چندان کار عاقلانه ای نباشد.
    دوم آنکه سازنده (Constructor) این کلاس به صورت Private تعریف شده است. علت این امر آن است که ما نه تنها تمایل نداریم بلکه به طور کلی معنی ندارد که کاربر (کسی که از این Library استفاده می کند) بتواند از این کلاس شیئی بسازد.

    - یکی از مواردی که شاید در برنامه نویسی مفید باشد، ایجاد کلاس ها در فضاهای نامی مناسب و لایه ای است، که البته در این زمینه اختلاف نظرهایی نیز وجود دارد. اجازه دهید موضوع را با یک مثال توضیح دهیم. فرض کنید که می خواهیم یک Library در رابطه با مدیریت فایل ها و پوشه ها مانند ایجاد پوشه، تغییر نام پوشه، حذف پوشه و غیره ایجاد نماییم و تصور کنید که برای انجام این عمل، به کلاسی با نام Utilities به شکل تعریف شده در مطلب قبلی نیاز داشته باشیم. حال سوال این است که این کلاس را در چه فضای نامی تعریف نماییم:

    راه حل اول: برخی بر این عقیده اند، برای اینکه بکارگیری Library آسان تر باشد، بهتر است در همان فضای نامی که مایکروسافت تعریف کرده است، مشخص شود:

    namespace System.IO
    {
    public sealed class Utilities
    {
    private Utilities(){}

    public static bool CreateFolder(string pathName)
    {
    bool blnResult = true;

    return(blnResult);
    }
    }
    }

    یکی از مزیت هایی که در این روش مستتر می باشد این است که کاربری که سالها با فضای نامی System.IO کار کرده، برای استفاده از کلاس Utilities شما، دیگر نیازی به مطالعه فضاهای نامی که در مستندات خود مشخص کرده اید، نخواهد داشت! و به راحتی می تواند در قسمت های مختلف برنامه، از کلاس شما استفاده نماید:

    System.IO.Utilities.CreateFolder("C:\\Temp  ");

    راه حل دوم: راه حل دوم نیز بی شباهت به راه حل اول نمی باشد، در این روش به جای استفاده از کلمه System از نام شخص یا شرکت سازنده استفاده می شود و به ازای هر یک از لایه های فضای نامی یک پوشه در ریشه پروژه ایجاد می شود. به عنوان نمونه تصور کنید که شرکت ایران خودرو تمایل دارد که یک Library به شکل فوق ایجاد نماید. در این صورت ابتدا در ریشه پروژه، یک پوشه به نام IranKhodro ایجاد کرده و در داخل آن پوشه دیگری به نام IO ایجاد می نماید و سپس در داخل پوشه IO کلاسی به شکل ذیل ایجاد می نماید:

    namespace IranKhodro.IO
    {
    public sealed class Utilities
    {
    private Utilities(){}

    public static bool CreateFolder(string pathName)
    {
    bool blnResult = true;

    return(blnResult);
    }
    }
    }

    در این نمونه نیز کاربر به راحتی می تواند با سابقه ذهنی که از فضاهای نامی مایکروسافت دارد و تنها با جایگزینی کلمه System به IranKhodro به تابع مورد نظر خود دسترسی پیدا کند:

    IranKhodro.IO.Utilities.CreateFolder("C:\\  Temp");

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

    - شرمنده! می دانم که خسته شده اید!! ولی یه چند لحظه تحمل کنید تا این نکته آخر را نیز خاطر نشان نمایم. به عنوان حسن ختام، پیشنهاد می کنم که تمامی توابعی که تعریف می کنید، چه توابعی که به صورت استاتیک تعریف می کنید و چه توابعی که به صورت غیر استاتیک تعریف می نمایید، باید (بهتر است) به صورت امری تعریف کرده و با یک فعل آغاز نمایید. این مطلب در ادبیات شیء گرایی بسیار حائز اهمیت می باشد. به عنوان نمونه بکارگیری توابعی که با کلماتی همچون Get, Put, Set و غیره آغاز می شوند، بسیار مناسب تر می باشد.



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

    - هرچند که در زمان طراحی و پیاده سازی کلاسها، امکان تعریف فیلدهای Public وجود دارد، ولی به عنوان یک برنامه نویس حرفه ای به هیچ وجه از فیلدهای Public استفاده ننمایید!. حال ممکن است از خود سوال نمایید که چگونه می توان فیلدهای Public را شبیه سازی نمود؟ بسیار ساده است! شما بهتر است فیلدهایی را که می خواهید Public تعریف نمایید، به صورت Private تعریف نموده و برای قابل دسترس بودن آنها به طور متناظر از Property استفاده نمایید:

    روش نادرست:

    public int Age;

    روش صحیح:


    private int _age;

    public int Age
    {
    get
    {
    return(_age);
    }
    set
    {
    _age = value;
    }
    }

    توجه: دلایل عدم استفاده از فیلدهای Public بسیار زیاد می باشد و از حوصله این مقاله خارج است.

    - یکی دیگر از مواردی که در زمان طراحی و پیاده سازی کلاس ها حائز اهمیت می باشد، نحوه نامگذاری متغیرها می باشد. البته لازم به ذکر است که استانداردهای متفاوتی در این زمینه وجود دارد که شخصا استاندارد ذیل را مطلوب تر ارزیابی کرده و بسیار علاقه مندم که دیگر دوستان، ما را با استانداردهای دیگری نیز آشنا نمایند. استانداردی که در ذیل عنوان خواهد شد، یکی از استانداردهای استفاده شده در زبان برنامه نویسی Java بوده که طبعا بکارگیری آن در زبان برنامه نویسی #C، خالی از لطف نمی باشد:

    1- در این استاندارد، اسامی فیلدهای Public و Property ها با حرف اول بزرگ آغاز شده و بقیه حروف، به صورت کوچک نوشته می شوند. مانند کلمات: Age و FullName

    دقت کنید که اگر نام فیلد مانند FullName از چند کلمه تشکیل شده باشد، قاعده مذکور در مورد هر کلمه صادق می باشد.

    2- فیلدهای Private و Protected مانند فیلدهای Public و Property ها بوده و تنها تفاوت آنها این است که حرف اول، اولین کلمه آن با حروف کوچک آغاز گردد و قبل از آن از Underline استفاده می شود. مانند کلمات: age_ و fullName_

    3- پارامترهای ورودی توابع نیز مانند فیلدهای Public و Property ها تعریف شده و تنها کافی است که حرف اول، اولین کلمه آن با حروف کوچک آغاز گردد. مانند کلمات: age و fullName

    4- متغیرهای تعریف شده در داخل توابع و Block ها نیز مانند فیلدهای Public و Property ها تعریف شده و تنها کافی است که مشخصه یا نوع آنها، ترجیحا با سه حرف کوچک در قبل از آنها قرار بگیرد. مانند کلمات: intAge و strFullName

    نمونه ذیل را با هم می بینیم:



    public class Person
    {
    private string _fullName;

    public string FullName
    {
    get
    {
    return(_fullName);
    }
    set
    {
    _fullName = value;
    }
    }

    public Person(string fullName)
    {
    string strFullName = "Dariush Tasdighi!";

    if(fullName == "")
    FullName = strFullName;
    else
    FullName = fullName;
    }
    }

  2. #2
    :flower: :موفق:

  3. #3
    کاربر دائمی آواتار afsar
    تاریخ عضویت
    مرداد 1383
    محل زندگی
    شیراز
    پست
    181
    :flower:

  4. #4
    کاربر دائمی
    تاریخ عضویت
    آبان 1383
    محل زندگی
    تهران
    پست
    133
    مرسی
    در مورد بخش اول بنده ترجیح می‌دهم کدی که می‌نویسم خلوت تر باشد. لذا در مورد "فضانام‌های" پرکاربرد از using استفاده می‌کنم و در فقط در مواردی که از فضانامی استفاده شود که کم‌تر استفاده شود، یا فضانام‌هایی که توسط خودمان تولید شده‌اند از نام کامل استفاده می‌کنم.

    از آنجاییکه اکثر برنامه نویسان بی حوصله هستند، کل فضاهای نامی سورس کد اولیه را کپی کرده و سورس کد خود را با حجمی بیهوده از فضاهای نامی مزین می کنند!
    برای جلوگیری از این گونه مزین کاری ها کافی است امور را به ReSharper بسپارید. این AddIns پس از نصب، همچنان که شما کد می‌نویسید، کدهای شما را تحلیل کرده و پیشنهادهای مناسبی را ارائه می‌دهد.
    از جمله حذف فضانام‌های بدون استفاده (فقط با یک کلیک)، حذف متغیرهای بدون استفاده و ...
    البته ویژگیهای دیگری نیز دارد که چون خارج از بحث هستش اشاره نمی‌کنم.

    اضافه شد:
    <span dir=ltr>http://www.jetbrains.com/resharper/</span>

  5. #5
    کاربر دائمی آواتار Beyondsoft
    تاریخ عضویت
    تیر 1384
    محل زندگی
    ایران
    پست
    336
    به نظر من اصلا کار خوبی نیست که زیاد از namespace استفاده کرد
    چون در جایی وقت ها تداخل پیش می آید
    به طور مثال دو تابع مختلف که یک نام دارند در namespace ها مختلف وجود دارد
    که با این کار می شکل پیش می آید .

  6. #6
    کاربر دائمی آواتار M.GhanaatPisheh
    تاریخ عضویت
    اردیبهشت 1383
    محل زندگی
    ----------
    پست
    1,267
    راه عاقلانه همونیه که کامران کمایی گفت :

    ""لذا در مورد "فضانام‌های" پرکاربرد از using استفاده می‌کنم و در فقط در مواردی که از فضانامی استفاده شود که کم‌تر استفاده شود، یا فضانام‌هایی که توسط خودمان تولید شده‌اند از نام کامل استفاده می‌کنم""

  7. #7
    خیلی خوب بود ممنون

  8. #8
    باز هم مثل همیشه کار آقای زواری خیلی درسته

  9. #9
    کاربر تازه وارد
    تاریخ عضویت
    خرداد 1384
    محل زندگی
    Merikh
    پست
    51
    سلام
    خیلی جالب بود.
    ممنون

  10. #10

    Exclamation نظرات شخصی.

    استاد تصدیقی، استاد من هستند و من بارها سر کلاسهای حضوری ایشون حاضر شدم.
    نظرات زیر صرفا شخصی هستن من قصد توهین ندارم پیشاپیش گه کدورتی پیش اومد من معذرت می‏خوام.
    زمانیکه برنامه را Compile می کنند، با هزاران خطا مواجه می شوند!
    در C#‎ 2.0 این مشکل حل شده و خود IDE باهوش usingها رو ست می‏کنه پس از این بابت نگرانی نداریم.
    در تعریف این کلاس، از کلمه sealed استفاده شده است.
    لزومی نداره. من ترجیح می‏دم از private ctor استفاده کنم و بجای sealed از static. چون حداقل یه حسن بزرگ داره. گاهی واسم پیش اومده که اشتباها از کلمه static قبل از تعریف متد استفاده نکردم. و تو source با تعجب دیدم که متدم تو Intellisense نمیاد. ولی با static کردن کلاس، خود کامپایلر به این موضوع گیر می‏ده.
    بهتر است فیلدهایی را که می خواهید Public تعریف نمایید، به صورت Private تعریف نموده و برای قابل دسترس بودن آنها به طور متناظر از Property استفاده نمایید
    این گفته انصافا عالیه. من حداقل 5 دلیل خیلی محکم دارم.
    با تشکر.

  11. #11
    مفیدبود

    بهتر است فیلدهایی را که می خواهید Public تعریف نمایید، به صورت Private تعریف نموده و برای قابل دسترس بودن آنها به طور متناظر از Property استفاده نمایید
    میشه چندتا از دلیلهارو بفرمایید.

  12. #12

    Lightbulb The reasons


    The primary use of a field should be as an implementation detail. Fields should be private or internal and should be exposed by using properties. Accessing a property is as easy as accessing a field, and the code in a property's accessors can change as the type's features expand without introducing breaking changes. Properties that just return the value of a private or internal field are optimized to perform on par with accessing a field; there is no performance gain associated with using externally visible fields over properties.
    Externally visible refers to public, protected, and protected internal (Public, Protected, and Protected Friend in Visual Basic) accessibility levels.


    Externally visible fields do not provide any benefits that are unavailable to properties. Additionally, public fields cannot be protected by Link Demands.

  13. #13
    کاربر تازه وارد آواتار barnamenevisjma
    تاریخ عضویت
    شهریور 1388
    محل زندگی
    بجنورد
    پست
    93

    نقل قول: نظرات شخصی.

    [html]من ترجیح می‏دم از private ctor استفاده کنم[/html]
    میشه در مورد این کمی توضیح بدین.
    مرسی

قوانین ایجاد تاپیک در تالار

  • شما نمی توانید تاپیک جدید ایجاد کنید
  • شما نمی توانید به تاپیک ها پاسخ دهید
  • شما نمی توانید ضمیمه ارسال کنید
  • شما نمی توانید پاسخ هایتان را ویرایش کنید
  •