شیوه جذب نیرو

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

لزوم استفاده از پروژه‌های کدباز دات‌نتی

سوال این است: چرا به عنوان یک برنامه‌نویس دات‌نت به هنگام استفاده از یک نرم‌افزار کاربردی که از آن فقط انتظار کاربردی داریم نه برنامه‌نویسی، باز هم بهتر است در صورت امکان از معادل دات‌نتی آن استفاده کنیم؟ مثلاً:

اولین دلیل این است که مشکلات نصب کمتری خواهیم داشت. به عنوان یک برنامه‌نویس دات‌نت آشنایی خیلی بیشتری با IIS و ویندوز داریم تا مثلاً Apache و لینوکس. راه اندازی MS SQL برایمان خیلی راحت‌تر از راه اندازی MySQL است. دلیل بعدی یادگیری است. اگر به اندازه کافی با یک پروژه کدباز دات‌نتی ور برویم احتمال این هست که بتوانیم از آن یک سری چیزها برای دنیا و آخرتمان یاد بگیریم. سومین دلیل مربوط به احتمال دستکاری است. اگر روزی روزگاری لازم شد که application مورد نظر را مختصر دستکاری کنیم، می‌توانیم امیدوار باشیم که به علت آشنایی با دات‌نت بهتر می‌توانیم این کار را انجام دهیم. فکرش را بکنید برای یک دستکاری کوچک مجبور به استفاده از Perl یا Ruby می‌شدید. دلیل آخر حفظ منافع جمعی (تعصب) است. ما با استفاده از یک پروژه دات‌نتی از آن حمایت کرده‌ایم. با این حمایت، برنامه‌نویس یا برنامه‌نویسان مورد نظر بیشر تشویق می‌شوند در دنیای دات‌نت کار کنند. و این در نهایت به نفع ما جامعه دات‌نت کارهاست.

ضرورت تکنولوژی

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

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

شکست نظامی ناشی از عدم استفاده از تکنولوژی روز فقط مختص به ما نیست:

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

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

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

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

می‌دانستید روزهایی در بورس تهران وجود داشته که انجام معاملات متوقف شده آن هم به این علت که نرم‌افزار هدایت معاملات، توانایی پردازش ارقامی بزرگتر از یک حد معین را نداشته؟ می‌دانستید سال‌هاست سازمان امور مالیاتی کشور به دنبال شرکتی می‌گردد که بتواند یک نرم‌افزار جامع مالیاتی تهیه کند ولی موفق نمی‌شود؟ می‌دانستید که یکی از نهادهای مهم کشور هرگز موفق نشده برای رفع نیازهای داخلی خودش به یک نرم‌افزار با قابلیت image processing از یک شرکت داخلی نرم‌افزار تهیه کند؟ آیا می‌دانستید که در زمان شروع پروژه کارت ملی شایع بود که به علت ناتوانی ایرانی‌ها، یک شرکت هندی نرم‌افزارهای مورد نیاز برای پروژه کارت ملی را تهیه کرده؟ آیا می‌دانستید…

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

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

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

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

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

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

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

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

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

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

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

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

‫آیا NHibernate انتخاب خوبی به عنوان یک ORM است؟

اگر در مورد لزوم استفاده از ORM به جواب مثبت رسیده‌اید، انتخاب یک ORM کار چندان  سختی نیست. در حال حاضر ORMهای تجاری و غیر تجاری زیادی وجود دارند از جمله ADO.NET Entity Framework، LLBLGen Pro، SubSonic و… برای دیدن فهرست آنها می‌توانید به این لینک مراجعه کنید.

NHibernate یک ORM کد باز است که از دنیای جاوا وارد دات‌نت شده است. کد باز بودن آن خود به خود مزایای زیادی ایجاد می‌کند. از جمله: جامعه استفاده کنندگان بیشتر، تنوع محصولات جانبی، عدم نیاز به کرک و قفل‌شکنی، عدم وابستگی به ‎.Net Framework و…

از آنجا که NHibernate بر اساس پروژه‌ی جاوایی Hibernate ایجاد شده از تمام تکنیک‌ها و منابع آموزشی آن می‌توان در NHibernate نیز استفاده کرد. NHibernate مدت‌هاست که چه در جاوا و چه در دات‌نت مورد استفاده است و منابع، نمونه کدها و پروژه‌های زیادی بر اساس آن به وجود آمده.

در مورد NHibernate پروژه‌های جانبی زیادی وجود دارد که کار کردن با آن را خیلی راحت‌تر ساخته است. مثلاً Fluent NHibernate به عنوان ابزاری که با کمک آن دیگر نیازی به استفاده از Xml Mappingهای NHibernate یعنی HBMها وجود ندارد. NHibernate Profiler ابزاری برای بازرسی و افزایش سرعت NHibernate. پروژه‌ی Castle ActiveRecord به عنوان ابزار راحت‌کننده‌ی کار با NHibernate و چندین پروژه‌ی مفید دیگر.

یکی از نگرانی‌های همیشگی در کار با ORMها Performance است. مسلماً هر ORMی مقدار کمی سرعت را کاهش می‌دهد. چون ORM یک لایه‌ی اضافی بر روی ADO.NET است. اما این موضوع در برابر دیگر مزایایی که استفاده از ORM به دست می‌دهد قابل اغماض است. البته این کاهش سرعت عمدتاً به علت عدم تنظیم صحیح ORM یا طراحی غلط Class Diagram است و می‌توان آن را تا اندازه‌ی زیادی از بین برد.

در این مورد که آیا NHibernate را می‌توان در پروژه‌های بزرگ به کار برد یا نه فکر نمی‌کنم در مورد پروژه‌هایی که داخل کشور به کار می‌روند مشکل خاصی ایجاد کند. تصور من این است که NHibernate خودش یک چیزی مثل ADO.NET است و می‌تواند بدون توجه به بزرگی یا کوچکی پروژه، یک Performance قابل قبول را از خودش به نمایش بگذارد.

ما در شرکت قبلی استفاده‌های خیلی خوبی از NHibernate کرده و از خیلی از مزایای آن بهره برده بودیم. اما متاسفانه در مقوله‌ی Performance مشکلاتی داشتیم که باز هم  عمدتاً مربوط به عدم استفاده صحیح ما از NHibernate بود. مطمئنم که با استفاده مناسب‌تر و داشتن دانش فنی عمیق‌تر از NHibernate می‌توانستیم مشکل Performance را هم از سر راه برداریم. با این وجود توصیه‌ام به کسانی که قصد استفاده از NHibernate را دارند این است که قبل از شروع حسابی مستندات آن را مطالعه کنند و یکی دو نمونه هم با آن بسازند. ضمناً در مورد طراحی Class Diagramهای دیتابیسی نهایت دقت را به عمل آورند در غیر این صورت حسابی به دردسر خواهند افتاد.

یکی از مشکلات موجود با NHibernate، راه‌اندازی اولیه آن است. منظور از راه‌اندازی اولیه، نوشتن Data Access Layer برنامه با استفاده از آن است. این کار علاوه بر این که وقت‌گیر و حوصله‌بر است، کار حساسی نیز هست. چون در صورت طراحی غلط مشکلات زیادی به وجود خواهد آمد. توصیه این است که برای رفع این مشکل از پروژه‌ی Castle ActiveRecord استفاده کنید. ActiveRecord تقریباً یک Data Access Layer کامل است که کار با NHibernate را به شدت راحت‌تر می‌کند. خصوصاً این که با Castle ActiveRecord مشابه Fluent NHibernate دیگر نیازی به Xml Mapping وجود ندارد. علاوه بر این چون Castle ActiveRecord بر اساس NHibernate نوشته شده تمام امکانات NHibernate را هم هنوز می‌توان با آن استفاده کرد. مثلاً می‌توان با NHibernate.ISession به طور مستقیم در Castle ActiveRecord کار کرد.

توجه: این مطلب در ادامه نوشته‌ی «آیا ORM برای ما مناسب است؟» نوشته شده است.

‫آیا ORM برای ما مناسب است؟

یکی از دوستان می‌خواهد بداند آیا استفاده از NHibernate در یک پروژه‌ی بزرگ با توجه به تجربه‌های قبلی آن، کار درستی است یا نه. این سوال را باید به دو قسمت تقسیم کرد. اول این که آیا استفاده از ORM به طور کلی کار درستی است یا نه. و دوم این که آیا استفاده از NHibernate به عنوان ORM کار درستی است یا نه. در این نوشته به سوال اول می‌پردازیم: آیا استفاده از ORM برای شرکت ما کار درستی است؟ سوال دوم در نوشته‌ی دیگری مورد بررسی قرار خواهد گرفت.

در دنیای Object Oriented Programming کار مستقیم با دیتابیس یک معضل حساب می‌شود. چون به خاطر ماهیت رابطه‌ای بودن آنها نمی‌شود با آنها مثل object برخورد کرد. به همین خاطر ORMها به وجود آمدند تا دیتابیس را زیر خودشان مخفی کرده و آن را به شیوه‌ی مناسب object oriented به لایه‌های بالاتر تحویل دهند.

برای استفاده کامل از امکانات ORM باید همه اصول Object Oriented Programming رعایت شود. یعنی تعریف کلاس‌ها، اینترفیس‌ها و روابط بین آنها باید مطابق اصول باشد. مثلاً اگر عادت به استفاده از متغیرهای عمومی دارید، اگر متودها را فقط به صورت استاتیک می‌نویسید، اگر متودهایی می‌نویسید که گاه به ۵۰۰ خط هم می‌رسند، اگر عادت به استفاده از مفاهیم سه‌گانه OOP ندارید، اگر نمی‌دانید Design Pattern چیست و… باید روش خود را تغییر دهید در غیر این صورت استفاده از ORM نه تنها هیچ مزیتی برای شما ندارد بلکه شما را حسابی هم به دردسر خواهد انداخت.

در بحث Documentation در ORM و دیتابیس، مهم‌ترین موضوعی که با آن برخورد می‌کنید این است که دیگر اجازه استفاده از ERD ندارید. بلکه به جای آن باید از UML Class Diagram استفاده کنید. چون ERD بر اساس ماهیت رابطه‌ای است ولی Class Diagram بر اساس ماهیت Object Oriented ساخته شده. اگر افراد گروه شما به ERD عادت دارند و نمی‌توانند یا نمی‌خواهند از Class Diagram استفاده کنند، این یعنی یک زنگ خطر. چون این افراد بعدها مشکلات زیادی را به وجود خواهند آورد.

تعامل با دیتابیس یکی از بنیادی‌ترین تغییراتی است که استفاده از ORM ایجاد می‌کند. ORMها این تفکر را تبلیغ می‌کنند که عملیات داده‌ای در سمت کد اتفاق بیفتند نه در داخل دیتابیس. این یعنی حداقل استفاده از امکانات داخلی دیتابیس. به عبارت دیگر اگر می‌خواهید از ORM استفاده کرده و از همه مزایای بهره‌مند شوید باید استفاده از Stored Procedureها، Viewها، Triggerها و… را بی‌خیال شوید. حال اگر در شرکتی هستید که همه Business برنامه را از طریق Stored Procedureها، Triggerها، Viewها و… اعمال می‌کنند، بدانید که استفاده از ORM در آنجا خیلی سخت بوده و مخالفان سرسخت زیادی خواهد داشت.

تجربه‌ای که ما در شرکت قبلی داشتیم در بعضی جاها با خودش شکست به همراه داشت. البته میزان موفقیت در استفاده از ORM از نظر شخص خودم حداقل ۷۵ درصد بود. متاسفانه علت آن بخش‌های ناموفق فقر دانش خودمان در استفاده از ORM بود. مهم‌ترین آن‌ها عبارتند از:

۱- چون نتوانسته بودیم ORM خودمان را به خوبی Config کنیم دچار مشکل Performance شده و مجبور شده بودیم بعضی جاها استثنا قائل شده و از Store Procedure استفاده کنیم.

۲- در صفحات ASP.NET برای Data Binding از ObjectDataSource استفاده نکرده بودیم در نتیجه مجبور شده بودیم بیشتر کارها از جمله Paging و… را از طریق code behind انجام دهیم. این موضوع باعث حجیم شدن و پیچیده شدن بیهوده‌ی code behind شده بود. علت عدم استفاده از ObjectDataSource نا آگاهی خودمان بود ولی به هر صورت اگر از به جای ORM از ADO.NET استفاده می‌کردیم کمتر دچار این مشکلات می‌شدیم.

۳- ما برای گزارش‌گیری از MS SQL Server Reporting Services استفاده می‌کردیم. گزارشات در این سیستم به دو نوع client و server تقسیم می‌شوند. ما بلد نبودیم یا شاید هم راهی وجود نداشت که خروجی‌های objectی مثل IList را به گزارشات سروری بفرستیم. در نتیجه آنجا هم مجبور شدیم برای تهیه گزارشات به صورت مستقیم از Sql استفاده کنیم.

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