اشتراک‌ها
کنترل Ctrl + c در برنامه نویسی کنسول
در برنامه نویسی کنسول یا text mode لازم است در هنگامی که برنامه در حال انجام یک کار طولانی و سنگین است کاربر بتواند انصراف خود را اعلام کند که از کلید ترکیبی استاندارد ctrl + c استفاده می‌شود. در این مقاله اموزش داده می‌شود چگونه این مکانیزم را در برنامه خود داشته باشیم.
کنترل Ctrl + c در برنامه نویسی کنسول
نظرات مطالب
Contact me
متاسفانه این دلیل عمده‌ای است که کمتر کتاب با کیفیت کامپیوتری فارسی رو می‌تونید پیدا کنید که حاصل تحقیق برای مثال 6 ماه (یا بیشتر) یک شخص باشد. عمدتا کتاب‌های برنامه نویسی در سه سوت و خودآموز در 5 روز و غیره که به نظر قسمتی از آن ترجمه‌ی ماشینی است و قسمتی هم ادیت دستی برای تولید انبوه سریعتر.
تا زمانی که نشود به عنوان یک شغل به آن نگاه کرد و به صورت اقساطی بعد از 6 ماه از تاریخ انتشار کتاب آن هم به میزان 9 تا 10 درصد پشت جلد را به شما بدهند ... کیفیت بازار نشر تخصصی ما به همین صورت خواهد بود.
مطالب
کش کردن اطلاعات غیر پویا در ASP.Net - قسمت سوم

در دو قسمت قبل در مورد IIS7 و IIS6 صحبت شد (+ و +).
در تکمیل قسمت دوم، یک مورد هم جزو قابلیت‌های ذاتی IIS6 و همچنین IIS5 است که می‌توان آن‌را فعال نمود (اگر دسترسی به سرور دارید) :




تنظیم مدت زمان content expiration ، بدون نیاز به برنامه نویسی خاصی، کار اضافه کردن هدر مربوط به مدت زمان کش شدن سمت کلاینت را به محتویات غیرپویای سایت شما مانند تصاویر ، فایل‌های CSS و غیره انجام می‌دهد. آمارها نشان می‌دهند که این تنظیم، زمان بارگذاری بعدی را بین 50 تا 70 درصد کاهش می‌دهد.
تنظیم این قابلیت را می‌توانید به چک لیست نصب IIS خود اضافه نمائید.

مطالب
Functional Programming یا برنامه نویسی تابعی - قسمت سوم – Immutability

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

  • Immutability: عدم توانایی تغییر داده
  • State: داده‌هایی که در طول زمان تغییر می‌کنند
  • Side Effect: تغییری که روی داده‌ها اتفاق می‌افتد

در قطعه کد زیر سعی شده‌است تفاوت یک کلاس Stateless و stateful را به سادگی نشان دهیم:

    //Stateful
    public class UserProfile
    {
        private User _user;
        private string _address;

        public void UpdateUser(int userId, string name)
        {
            _user = new User(userId, name);
        }
    }

    //Stateless
    public class User
    {
        public User(int id, string name)
        {
            Id = id;
            Name = name;
        }

        public int Id { get; }
        public string Name { get; }
    }


چرا Immutable بودن مهم است؟ 

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

در واقع انتظار داریم که به ازای یک ورودی بر اساس بدنه‌ی متد، یک خروجی داشته باشیم؛ ولی در واقعیت تاثیری که اجرای متد بر روی state کل کلاس خواهد گذاشت، از دید ما پنهان است و باعث به وجود آمدن مشکلات بعدی خواهد شد. برای مثال قطعه کد بالا را به صورت Honest بازنویسی میکنیم: 

    public class UserProfile
    {
        private readonly User _user;
        private readonly string _address;

        public UserProfile(User user,string address)
        {
            _user = user;
            _address = address;
        }
        public UserProfile UpdateUser(int userId, string name)
        {
            var newUser = new User(userId, name);
            return  new UserProfile(newUser,_address);
        }
    }

    public class User
    {
        public User(int id, string name)
        {
            Id = id;
            Name = name;
        }

        public int Id { get; }
        public string Name { get; }
    }

در این مثال متد UpdateUser به جای  void، یک شی از جنس کلاس UserProfile را بر می‌گرداند. کلاس UserProfile هم برای وهله سازی نیاز به یک شیء از جنس User و Address را دارد. بنابراین مطمئن هستیم که مقدار دهی شده‌اند. نکته دیگر در قطعه کد بالا این است که به ازای هر بار فراخوانی متد، یک شیء جدید بدون وابستگی به وهله سازی اشیاء دیگر، برگردانده میشود.


Immutable بودن باعث می‌شود: 

  • خوانایی کد افزایش پیدا کند
  • جای واحدی برای Validate کردن داشته باشیم
  • به صورت ذاتی Thread Safe باشیم


در مورد محدودیت‌هایی که در کار با اشیاء Immutable باید در نظر داشته باشیم، می‌توان به مصرف بالای رم و سی پی یو، اشاره کرد. در واقع به نسبت حالت mutate، تعداد اشیاء بیشتری ساخته خواهند شد. در فریمورک دات نت برای کار با اشیا immutable امکاناتی در نظر گرفته شده که این هزینه را کاهش می‌دهند. به طور مثال می‌توانیم از کلاس ImmutableList استفاده کنیم و از ایجاد اشیاء اضافه‌تر و تحمیل بار اضافی به GC جلوگیری کنیم. یک مثال: 

//Create Immutable List
ImmutableList<string> list = ImmutableList.Create<string>();
ImmutableList<string> list2 = list.Add("Salam");

//Builder
ImmutableList<string>.Builder builder = ImmutableList.CreateBuilder<string>();
builder.Add("avali");
builder.Add("dovomi");
builder.Add("sevomi");

ImmutableList<string> immutableList = builder.ToImmutable();


چطور با side effect کنار بیایم؟ 

یکی از الگوهای رایج برای این کار، مفهوم جدا سازی Command/Query است. به طور ساده تمامی عملیاتی را که تاثیر گذار هستند، به صورت Command در نظر میگیریم. Command ‌ها معمولا هیچ نوعی را بازگشت نمیدهند و همینطور بر عکس این قضیه برای Query ‌ها صادق است. اشتباه رایج درباره این الگو، محدود کردن این الگو به معماری‌های خاصی مانند Domain Driven می‌باشد؛ در صورتیکه الزامی برای رعایت این الگو در سایر معماری‌ها وجود ندارد. 

به مثال زیر دقت کنید. سعی کردم قسمت‌های Command و Query را از هم جدا کنم: 

در واقع هر برنامه می‌تواند شامل دو قسمت باشد:

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

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

برای مسائلی که در بالا صحبت شد، نمونه‌‌ای را آماده کرده‌ام. این نمونه به طور ساده یک سیستم مدیریت نوبت است که نوبت‌ها را در فایلی ذخیره و بازیابی میکند ( mutate ) و منطق مربوط به نوبت‌ها و زمان ویزیت آن میتواند به صورت immutable پیاده سازی شود. این کد در دو حالت functional و غیر functional پیاده سازی شده تا به خوبی تفاوت آن را در حالت قبل و بعد از برنامه نویسی تابعی بتوانیم درک کنیم. به جهت خوانایی بیشتر و دسترسی به کد‌ها، آن‌ها را روی گیت‌هاب قرار داده و شما میتوانید از اینجا سورس کد مورد نظر را بررسی کنید. سعی شده در این مثال تمامی مواردی که در این قسمت ذکر شد را پیاده سازی کنیم. امیدوارم که مطالب مربوط به برنامه نویسی تابعی یا functional programming توانسته باشد دیدگاه جدیدی را به کدهایی که مینویسیم بدهد. در  قسمت‌های بعدی به مواردی مانند مدیریت exception ‌ها و کار با null ‌ها و ... خواهیم پرداخت.

مطالب
داستانی از Unicode
یکی از مباحثی که به نظرم هر دانشجوی رشته کامپیوتر، فناوری اطلاعات و علاقمند به این حوزه باید بداند بحث کاراکترهاست؛ جدا از اینکه همه ما در مورد وجود ascii یا UTF-8 و ... و توضیحات مختصر آن اطلاع داریم ولی عده‌ای از دوستان مثل من هنوز اطلاعات پایه‌ای‌تر و جامع‌تری در این باره نداریم؛ در این مقاله که برداشتی از وب سایت smashing magazine  و W3 است به این مبحث می‌پردازیم.
کامپیوترها تنها با اعداد سر و کار دارند نه با حروف؛ پس این بسیار مهم هست که همه کامپیوترها بر روی یک سری اعداد مشخص به عنوان نماینده‌ای از حروف به توافق برسند. این توافق یکسان بین همه کامپیوترها بسیار مهم هست و باید طبق یک استاندارد مشترک استفاده شود تا در همه سیستم‌ها قابل استفاده و انتقال باشد؛ برای همین در سال 1960 اتحادیه استاندارهای آمریکا، یک سیستم رمزگذاری 7 بیتی را ایجاد کرد؛ به نام American Standard Code for Information Interchange یا کد استاندارد سازی شده آمریکایی برای تبادل اطلاعات یا همان ASCII. این هفت بیت به ما اجازه می‌داد تا 128 حرف را کدگذاری کنیم. این مقدار برای حروف کوچک و بزرگ انگلیسی و هم چنین حروف لاتین، همراه با کدگذاری ارقام و یک سری علائم نگارشی و کاراکترهایی از قبیل space ، tab و موارد مشابه و نهایتا کلیدهای کنترلی کافی بود. در سال 1968 این استاندارد توسط رییس جمهور وقت آمریکا لیندون جانسون به رسمیت شناخته شده و همه سیستم‌های کامپیوتری ملزم به رعایت و استفاده از این استاندارد شدند.
برای لیست کردن و دیدن این کدها و نمادهای حرفیشان می‌توان با یک زبان برنامه نویسی یا اسکریپتی آن‌ها را لیست کرد. کد زیر نمونه‌ای از کد نوشته شده در جاوااسکریپت است.
 <html> 

<body>
 <style type="text/css">p {float: left; padding: 0 15px; margin: 0;}</style> 

<script type="text/javascript">
 for (var i=0; i<128; i++) document.writeln ((i%32?'':'<p>') + i + ': ' + String.fromCharCode (i) + '<br>'); 

</script>
</body>
 </html>
در سال‌های بعدی، با قوی‌تر شدن پردازش‌گرها و 8 بیت شدن یک بایت به جای ذخیره 128 عدد توانستند 256 عدد را ذخیره کنند ولی استاندارد اسکی تا 128 کد ایجاد شده بود و مابقی را به عنوان ذخیره نگاه داشتند. در ابتدا کامپیوترهای IBM از آن‌ها برای ایجاد نمادهای اضافه‌تر و همچنین اشکال استفاده می‌کرد؛ مثلا کد 200 شکل  ╚ بود که احتمالا برنامه نویسان زمان داس، این شکل را به خوبی به خاطر میاورند یا مثلا حروف یونانی را اضافه کردند که با کد 224 شکل آلفا  α بود و بعد‌ها به عنوان  code page 437  نامگذاری شد. هر چند که هرگز مانند اسکی به یک استاندارد تبدیل نشد و بسیاری از کشورها از این فضای اضافی برای استانداردسازی حروف خودشان استفاده می‌کردند و در کشورها کدپیج‌های مختلفی ایجاد شد. برای مثال در روسیه کد پیچ 885 از کد 224 برای نمایش Я بهره می‌برد و در کد پیچ یونانی 737 برای نمایش حرف کوچک امگا ω استفاده می‌شد. این کار ادامه داشت تا زمانیکه مایکروسافت در سال 1980 کد پیچ Windows-1251 الفبای سریلیک را ارئه کرد. این تلاش تا سال 1990 ادامه پیدا کرد و تا آن زمان 15 کدپیج مختلف استاندارسازی شده برای الفبایی چون سیریلیک، عربی، عبری و ... ایجاد شد که این استانداردها از ISO-8859-1 شروع و تا  ISO-8859-16 ادامه داشت و موقعی که فرستنده پیامی را ارسال می‌کرد، گیرنده باید از کدپیج مورد نظر مطلع می‌بود تا بتواند پیام را صحیح بخواند.
بیایید با یک برنامه علائم را در این 15 استاندارد بررسی کنیم. تکه کدی که من در اینجا نوشتم یک لیست را که در آن اعداد یک تا 16 لیست شده است، نشان میدهد که با انتخاب هر کدام، کدها را از 0 تا 255 بر اساس هر استاندارد به ترتیب نمایش می‌دهد. این کار توسط تعیین استاندارد در تگ متا رخ میدهد.
در زمان بارگذاری، استانداردها با کد زیر به لیست اضافه می‌شوند.در مرحله بعد لیستی که  postback را در آن فعال کرده‌ایم، کد زیر را اجرا می‌کند. در این کد ابتدا charset انتخاب شده ایجاد شده و سپس یکی یکی کدها را به کاراکتر تبدیل می‌کنیم و رشته نهایی را درج می‌کنیم: ( دانلود فایل‌های زیر )
 private String ISO = "ISO-8859-";
        protected void Page_Load(object sender, EventArgs e)
        {
            if (!IsPostBack)
            {
                for (int i = 1; i < 16; i++)
                {
                    ListItem item = new ListItem();
                    item.Text = ISO + i.ToString();
                    item.Value = i.ToString();
                    DropDownList1.Items.Add(item);
                }
                ShowCodes(1);
            }
           
        }

     
        protected void DropDownList1_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (DropDownList1.SelectedItem != null)
            {
                int value = int.Parse(DropDownList1.SelectedValue);
                ShowCodes(value);
            }
            
        }

        private void ShowCodes(int value)
        {
            Response.Charset = ISO + value;
            string s = "";
            for (int i = 0; i < 256; i++)
            {
                char ch = (char)i;
                s += i + "-" + ch;
                s += "<br/>";//br tag
            }
            Label1.Text = s;
        }

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

یونیکد نجات بخش
اواخر سال 1980 بود که پیشنهاد یک استاندارد جدید داده شد و در آن به هر حرف و یا نماد در هر زبانی یک عدد یکتا نسبت داده میشد و باید بیشتر از 256 عدد می‌بود که آن را یونیکد نامیدند. در حال حاضر یونیکد نسخه 601 شامل 110 هزار کد می شود. 128 تای آن همانند اسکی است. از 128 تا 255 مربوط به علائم و علامت‌هاست که بیشتر آن‌ها از استاندارد ISO-8859-1 وام گرفته شده‌اند. از 256 به بعد هم بسیاری از علائم تلفظی و ... وجود دارد و از کد 880 زبان یونایی آغاز شده و پس از آن زبان‌های سیریلیک، عبری، عربی و الی آخر ادامه می‌یابند. برای نشان دادن یک کد یونیکد به شکل هگزادسیمال U+0048 نوشته می‌شود و برای تبدیل آن به دسیمال 4*16+8=72 استفاده می‌شود. به هر کد یونیکد، کد پوینت code point گفته میشود.
در ویکی پدیای فارسی، یونیکد اینگونه توضیح داده شده است: "نقش یونیکد در پردازش متن این است که به جای یک تصویر برای هر نویسه یک کد منحصر به فرد ارایه می‌کند. به عبارت دیگر، یونیکد یک نویسه را به صورت مجازی ارایه می‌کند و کار ساخت تصویر (شامل اندازه، شکل، قلم، یا سبک) نویسه را به عهده نرم‌افزار دیگری مانند مرورگر وب یا واژه‌پرداز می‌گذارد. "
یونیکد از 8 بیت یا 16 بیت استفاده نمی‌کند و با توجه به اینکه دقیقا 110 ،116 کد را حمایت می‌کند به 21 بیت نیاز دارد. هر چند که کامپیوترها امروزه از معمار‌های 32 بیتی و 64 بیتی استفاده می‌کنند، این سوال پیش می‌آید که ما چرا نمی‌توانیم کاراکترها را بر اساس این 32 بیت و 64 بیت قرار بدهیم؟ پاسخ این سوال این‌است که چنین کاری امکان پذیر است و بسیاری از نرم افزارهای نوشته شده در زبان سی و سی ++ از wide character حمایت می‌کنند. این مورد یک کاراکتر 32 بیتی به نام wchar_t است که نوعی داده char توسعه یافته هشت بیتی است و بسیاری از مرورگرهای امروزی از آن بهره مند هستند و تا 4 بیلیون کاراکتر را حمایت می‌کنند.
شکل زیر دسته بندی از انواع زبان‌های تحت حمایت خود را در نسخه 5.1 یونیکد نشان می‌دهد:


کد زیر در جاوااسکریپت کاراکترهای یونیکد را در مرز معینی که برایش مشخص کرده‌ایم نشان می‌دهد:
 <html> 

<body>
 <style type="text/css">p {float: left; padding: 0 15px; margin: 0;}</style> 

<script type="text/javascript">
for (var i=0; i<2096; i++)
   document.writeln ((i%256?'':'<p>') + i + ': ' + String.fromCharCode (i) + '<br>'); 

</script>
</body>
 </html>

CSS & Unicode
یکی از جذاب‌ترین خصوصیات در css، خصوصیت Unicode-range است. شما میتوانید برای هر کاراکتر یا حتی رنج خاصی از کاراکترها، فونت خاصی را اعمال کنید. به دو نمونه زیر دقت کنید:
/* cyrillic */
@font-face {
  font-style: normal;
  src: local('Roboto Regular'), local('Roboto-Regular'), url(http://fonts.gstatic.com/s/roboto/v14/mErvLBYg_cXG3rLvUsKT_fesZW2xOQ-xsNqO47m55DA.woff2) format('woff2');
  unicode-range: U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
/* greek-ext */
@font-face {
  font-style: normal;
  src: local('Roboto Regular'), local('Roboto-Regular'), url(http://fonts.gstatic.com/s/roboto/v14/-2n2p-_Y08sg57CNWQfKNvesZW2xOQ-xsNqO47m55DA.woff2) format('woff2');
  unicode-range: U+1F00-1FFF;
}
/* greek */
@font-face {
  font-style: normal;
  src: local('Roboto Regular'), local('Roboto-Regular'), url(http://fonts.gstatic.com/s/roboto/v14/u0TOpm082MNkS5K0Q4rhqvesZW2xOQ-xsNqO47m55DA.woff2) format('woff2');
  unicode-range: U+0370-03FF;
}
/* vietnamese */
@font-face {
  font-style: normal;
  src: local('Roboto Regular'), local('Roboto-Regular'), url(http://fonts.gstatic.com/s/roboto/v14/NdF9MtnOpLzo-noMoG0miPesZW2xOQ-xsNqO47m55DA.woff2) format('woff2');
  unicode-range: U+0102-0103, U+1EA0-1EF1, U+20AB;
}
/* latin-ext */
@font-face {
  font-style: normal;
  src: local('Roboto Regular'), local('Roboto-Regular'), url(http://fonts.gstatic.com/s/roboto/v14/Fcx7Wwv8OzT71A3E1XOAjvesZW2xOQ-xsNqO47m55DA.woff2) format('woff2');
  unicode-range: U+0100-024F, U+1E00-1EFF, U+20A0-20AB, U+20AD-20CF, U+2C60-2C7F, U+A720-A7FF;
}
در صورتی که در Unicode-range، تنها یک کد مانند U+20AD نوشته شود، فونت مورد نظر فقط بر روی کاراکتری با همین کد اعمال می‌شود. ولی اگر بین دو کد از علامت - استفاده شود، فونت مورد نظر بر روی کاراکترهایی که بین این رنج هستند اعمال می‌شود U+0025-00FF و حتی می‌توان اینگونه نوشت ??U+4 روی کاراکترهایی در رنج U+400 تا U+4FF اعمال می‌شوند. برای اطلاعات بیش‌تر به اینجا و اینجا  مراجعه کنید.
به 65536 کد اول یونیکد Basic Multilingual Plan یا به اختصار BMP می‌گویند و شامل همه کاراکترهای رایجی است که مورد استفاده قرار می‌گیرند. همچنین یونیکد شامل یک فضای بسیار بزرگ خالی است که به شما اجازه توسعه دادن آن را تا میلیون‌ها کد می‌دهد. به کاراکترهایی که در این موقعیت قرار می‌گیرند supplementary characters یا کاراکترهای مکمل گویند. برای اطلاعات بیشتر می‌توانید به سایت رسمی یونیکد مراجعه کنید. در اینجا هم مباحث آموزشی خوبی برای یونیکد دارد، هر چند کامل‌تر آن در سایت رسمی برای نسخه‌های مختلف یونیکد وجود دارد.


UTF-8 نجات بخش می‌شود
بسیاری از مشکلات ما حل شد. همه حروف را داریم و مرورگر‌ها نیز همه حروف را میشناسند؛ ولی برای ما دو مشکل ایجاد کرده است:
  • بسیاری از نرم افزارها و پروتکل‌ها هنوز 8 بیتی کار می‌کنند.
  • اگر یک متن انگلیسی ارسال کنید، 8 بیت هم کافی است ولی در این حالت 32 بیت جابجا می‌شود؛ یعنی 4 برابر و در ارسال و دریافت و پهنای باند برایمان مشکل ایجاد می‌کند.
برای حل این مشکل استاندارهای زیادی چون USC-2 یا UTF-16 ایجاد شدند ولی در سال‌های اخیر برنده رقابت، UTF-8 بود که مخفف عبارت Universal Character Set Transformation Format 8 bit می‌باشد. این کدگذاری بسیار هوشمندانه عمل می‌کند. موقعی که شما کاراکتری را وارد می‌کنید که کدش بین 0 تا 255 است، 8 بیت به آن اختصاص می‌دهد و اگر در محدوده‌ای است که بتوان دو بایت را به آن اختصاص داد، دوبایت و اگر بیشتر بود، سه بایت و اگر باز بیشتر بود 4 بایت به آن اختصاص میدهد. پس با توجه به محدوده کد، تعداد بایت‌ها مشخص می‌شوند. بنابراین یک متن نوشته شده انگلیسی که مثلا از کدهای بین 0تا 128 استفاده می‌کند و فرمت ذخیره آن UTF-8 باشد به ازای هر کارکتر یک بایت ذخیره می‌کند.

مقایسه‌ای بین نسخه‌های مختلف :

همانطور که می‌بینید UTF-8 برای کاراکترهای اسکی، از یک بایت و برای دیگر حروف از دوبایت و برای بقیه BMP‌ها از سه بایت استفاده میکند و در صورتی که کاراکتری در ناحیه مکمل supplementary باشد، از چهار بایت استفاده خواهد کرد. UTF-16 از دو بایت برای نمایش کاراکترهای BMP و از 4 بایت برای نمایش کاراکترهای مکمل استفاده می‌کند و در UTF-32 از 4 بایت برای همه کاراکترها یا کد پوینت‌ها استفاده می‌شود.

مطالب
بررسی Bad code smell ها: کلاس بزرگ
این نوع کد بد بو در دسته بندی «کدهای متورم» قرار می‌گیرد. یکی از نتایج متورم شدن کدها، سخت شدن نگهداری آنهاست. بدیهی به نظر می‌رسد که نگهداری و اعمال تغییرات بر روی یک کلاس بزرگ، دشوار و زمان گیر خواهد بود. علارغم سادگی مفهوم این نوع کد بد بو، این مورد یکی از موارد پر تکرار درمحصول‌ها است.  
کلاس بزرگ کلاسی است که تعداد اعضای آن (فیلد، خصوصیت، متد) زیاد باشند و تعداد خطوط کد زیادی نیز داشته باشد. 

چرا چنین بویی به راه می‌افتد 

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

نشانه‌های این کد بد بو 

نشانه‌هایی که به تشخیص یک کلاس بزرگ کمک می‌کنند به صورت زیر هستند: 
  • تعداد خطوط زیاد: این معیار نسبت به فناوری و زبان برنامه نویسی مورد استفاده درمحصول متفاوت است؛ ولی در حالت کلی زمانیکه یک کلاس تعداد خطوط کدی بیشتر از 100 داشت، مشکلی بوجود آمده است. 
  • تعداد وضعیت‌های داخلی (در تعریف شیء گرایی) زیاد در یک کلاس، نشان دهنده بزرگی یک کلاس هستند.  
  • تعداد پارامترهای زیاد سازنده کلاس نشان دهنده متورم شدن کلاس هستند. معمولا مدیریت کردن تعداد وضعیت‌های داخلی زیاد منجر به دریافت تعداد زیاد پارامتر ورودی در سازنده می‌شوند. اگر قانون مربوط به تعداد پارامترهای یک متد را در نظر داشته باشیم و با فرض اینکه سازنده نیز یک متد است، حداکثر پارامترهای مناسب برای یک سازنده 4 خواهد بود. 
  • متغیرهایی وجود دارند که به صورت دسته‌ای پیشوند یا پسوند خاصی دارند. این پیشوندها یا پسوندها نشان دهنده مواردی هستند که احتمالا می‌توانند به کلاس مخصوص به خود انتقال داده شوند. زیرا از نظر منطقی ارتباطی بین آنها وجود دارد و مربوط به کلاس فعلی نمی‌شوند (زیرا اگر اینگونه بود نیازی به پیشوند یا پسوند نبود).


مشکل این کد بد بو چیست؟ 

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


چگونه این بو را رفع کنیم؟  

دیدگاه کلی برای رفع چنین بویی تقسیم مسئولیت‌های موجود در یک کلاس بزرگ است. این تقسیم می‌تواند به صورت‌های زیر انجام شود:
  • ایجاد کلاسی مستقل برای هریک از مسئولیت‌های موجود در کلاس بزرگ 
  • ایجاد کلاسی پایه (Base class) برای انجام برخی از امور مشترک در کلاس 


جمع بندی 

یکی از نکات مهم در مورد انواع کد بد بو متعلق به دسته کدهای متورم، توجه دایمی به کدهای نوشته شده در محصول است. زیرا کدهای متورم به مرور زمان و به آرامی ایجاد می‌شوند و معمولا توجه کافی به آنها نمی‌شود.  
نظرات مطالب
ویدیوهای رایگان آموزشی WPF
سلام
موفق باشید. می‌تونید مطالب جدید خودتون را در سایت زیر لینک دهید تا بقیه برنامه نویس‌ها نیز مطلع شوند
http://www.idevcenter.com
نظرات نظرسنجی‌ها
صبح‌کار هستید یا شب‌کار؟
جالبه که باور عمومی به اینه که برنامه نویس‌ها همگی از دم شب بیدار هستند. ولی نظر سنجی خلاف این موضوع را نشان می‌دهد.