اشکال زدایی اردکی

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

افراد راه حل‌های مختلفی برای این طور مواقع دارند. مثلاً بعضی‌ها به پیاده روی می‌روند، بعضی‌ها کار را تعطیل می‌کنند و به منزل بر می‌گردند، بعضی‌ها دوش می‌گیرند و… اما یک راه حل جالب دیگر وجود دارد: اشکال زدایی اردکی.

در این روش برنامه‌نویس یک اردک پلاستیکی (اسباب بازی) را روی میز گذاشته و تک تک خطوط برنامه را برایش توضیح می‌دهد. به این ترتیب امکان پیدا کردن خطا خیلی بالاتر می‌رود. تجربه نشان داده که توضیح دادن کامل برنامه به یک نفر دیگر می‌توان در پیدا کردن زودتر باگ موثر باشد. نام دیگر این روش «بلند فکر کردن» است.

‫کتاب اصول برنامه‌نویسی (Foundation of Programming)

کتاب «اصول برنامه‌نویسی» که یک کتاب الکترونیکی ۷۹ صفحه‌ای است، توسط یکی از فعالان CodeBetter منتشر شده. کلیت مطالب کتاب راجع به مفاهیم نسبتاً جدید تولید نرم‌افزار مثل Persistence، DI، DDD، Unit Test و غیره است. نویسنده در ابتدای کتاب اظهار داشته که این کتاب برای پشتیبانی از حرکت ALT.NET نوشته شده است. این کتاب همچون خود ALT.NET بیشتر روی مفاهیم و تکنیک‌ها مانور می‌دهد چون معتقد است برنامه‌نویسان به اندازه کافی به API دات‌نت مسلط شده‌اند پس حالا وقت آن است که اصولی‌تر برنامه بنویسند.

با دیدن بخش‌های اول کتاب ممکن است فکر کنید یک کتاب کلاسیک «مهندسی نرم‌افزار» را باز کرده‌اید. اما کتاب کار زیادی به تئوری ندارد و بلافاصله به مثال‌ها، نمونه‌ها و ابزارهای عملی می‌پردازد. البته واقعیت این است که می‌شود این کتاب را یک کتاب «مهندسی نرم‌افزار» عملی نامید. چون با معرفی تکنیک‌ها، روش‌ها و ابزارهایی به شما کمک می‌کند تا همان اصول فراموش شده «مهندسی نرم‌افزار» را عملاً به کار گیرید.

عناوین فصول کتاب:
۱- ALT.NET: معرفی جبهه ALT.NET و تفاوت آن با MSDN Way
‫‫۲-‫ Domain Driven Design: معرفی الگوی DDD‎
‫۳- ‫Persistence: ارتباط با دیتابیس و ذخیره داده‌ها‎
‫‫۴-‫ Dependency Injection: معرفی و ابزارها‏
۵- Unit Testing: تست واحد
۶- Object Relational Mappers: معرفی و استفاده از NHibernate
۷- کار با Memory به طور اصولی
۸- مدیریت Exceptionها
۹- Proxy و استفاده از آن
۱۰- جمع‌بندی

تاریخ این کتاب ۲۰۰۸ بوده و کمی قدیمی می‌باشد. اما با این وجود خواندن و به کارگیری آن به همه برنامه‌نویسان توصیه می‌شود.

نرم‌افزارهای داده‌ای در وب

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

به عنوان نمونه به پروژه‌های زیر توجه کنید:

۱- ترافیک مصنوعی: بازدید مصنوعی از یک سایت خاصی به طور مکرر. به طوری که سایت مذکور فکر کند بازدید کننده‌هایش از OSها و browserها مختلف آمده است.

۲- تبدیل فید RSS به تکست

۳- نرم‌افزار email marketing

پ. ن.: به نرم‌افزارهای web scraping هم نگاهی بیندازید.

‫لذت Low Level

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

اما این روزها حس Low Level دوستی‌ام با دو چیز به خوبی ارضا می‌شود. یکی ریزه‌کاری‌های NHibernate مثل Fetch Mode، First/Level Cache و Mappingها و دیگری ور رفتن با git به عنوان یک ابزار سورس کنترل غیر متمرکز. git و ساختار و نحوه استفاده آن آنقدر جذابیت دارد که می‌توان ساعت‌ها بدون بلند شدن از جلوی کامپیوتر با آن کار کرد.

تزریق انقلابی

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

در این طور موارد اگر فرد برنامه‌نویس آن قدر وقت و حوصله نداشته که همه این موارد را بررسی کرده و ضمناً معتقد باشد که feature مورد نظر چندان هم اثر بدی رو کلیت سیستم ندارد و می‌توان موارد جزیی به وجود آمده را بلافاصله رفع و رجوع کرد آن وقت می‌توان از یک روش انقلابی استفاده کرد. من اسم این روش را «تزریق انقلابی» گذاشته‌ام. به این معنی که ابتدا موارد اصلی بررسی شده و سپس feature مذکور بدون آن که توجه کسی (مشتری/کاربر/کارفرما/مدیر پروژه/…) به آن جلب شود به سیستم تزریق (اضافه) گردد. البته مدتی هم باید گوش به زنگ مشتری ماند تا هر گونه ایراد و اشکال احتمالی سریعاً برطرف گردد.

شباهت برنامه‌نویسی و آشپزی در ایران

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

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

‫if تنفر انگیز

به این if توجه کنید:
//code...

if (something != null)
{
Do1();
Do2();
}

//code...
در اینجا null نبودن بررسی شده و بر اساس آن یک سری عملیات انجام می‌شود. اما دقت کنید که اگر مقدار مورد نظر null باشد هیچ مکانیزمی برای اعلام خطا وجود ندارد و به سادگی هر چه تمام‌تر آن بخش از کد بی هیچ سر و صدایی skip خواهد شد. درست است که بعضی جاها null بودن لزوماً به معنای خطا نیست اما اگر نمونه کدی ببینید که تمام ifهای آن به همین سبک هستند حتماً از این ifها متنفر خواهید شد.

خواندن کتاب‌های کامپیوتری

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

دسته اول: ابزارها
شامل کتاب‌هایی که برای آشنایی و یادگیری ابزار خاصی نوشته شده‌اند. مثل:

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

دسته سوم: زبان/مفهوم
کتاب‌هایی که زبان‌های برنامه‌نویسی را آموزش می‌دهند، راجع به یک استاندارد صحبت می‌کنند یا مباحث آکادمیک مثل طراحی الگوریتم، لایه‌های شبکه، سیستم عامل و… را مورد بحث قرار می‌دهند. مثل:

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

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

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

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

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

‫استفاده از سورس‌های Online

گاهی اوقات که می‌خواهیم روش استفاده از فلان متود یا کلاس یک Library خاص را دانسته یا می‌خواهیم چند نمونه کد با آن پیدا کنیم، یک راهش استفاده از سورس‌های Online کتابخانه‌ی مورد نظر است. البته به شرط آن که Library یا برنامه‌ی مورد نظر Open Source بوده و سورس کد آن به صورت Online موجود باشد.

معمولاً سورس کد همه‌ی پروژه‌های Open Source به صورت Online نیز موجود است. مثلاً سورس کد NHibernate در این آدرس و سورس کد Castle ActiveRecord در این آدرس قرار دارد. این سورس‌ها منبع خوبی هستند برای که بیشتر از روش کار فلان بخش Library سر در بیاوریم. مثلاً اگر می‌خواهید بدانید متود ActiveRecordStarter.SchemaUpdate چطور از کلاس SchemaUpdate موجود در NHibernate استفاده می‌کند، کافی است نگاهی به سورس کد کلاس ActiveRecordStarter بیندازید.

پروژه‌های Open Source معروف معمولاً دارای Unit Test هم هستند. این Unit Testها پر هستند از نمونه‌های ساده از نحوه‌ی چگونگی استفاده از پروژه. به عنوان مثال اگر به دنبال نمونه کدی برای عملیات ذخیره، حذف یا بازیابی رکوردهای یک Entity در Castle ActiveRecord هستید کافی است به کد کلاس ActiveRecordTestCase مراجعه کنید.

از دیگر مزایای سورس‌های Online این است که همیشه در دسترس هستند، نیاز به Downloadهای متعدد ندارند و لینک آنها را به راحتی می‌توان از طریق ایمیل و غیره به این ور و اون ور فرستاد.

سیاست مچ‌گیری

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

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

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

۱- جلسات آموزشی متعدد و توجیه مفید بودن قاعده برای تیم.
۲- پیگیری‌های روزانه برای رعایت قاعده.
۳- راهنمایی چهره به چهره برای کسب اطمینان از این که افراد مشکلی در اجرای قاعده ندارند.
۴- ثابت قدم بودن در اجرای قاعده. رهرو آن نیست که گه آهسته و گه تند رود. رهرو آن است که آهسته ولی پیوسته برود.
۵- اعمال سیاست‌های تشویقی و تنبیهی.
۶- تطبیق قاعده‌ی مورد نظر با دنیای واقعی و کسب اطمینان از این که اجرای قاعده‌ی مورد نظر باعث نمی‌شود کسی احساس احمق بودن کند.