2010/12/31

وب‌سایت شخصی من

بالاخره من هم در آخرین روز سال ۲۰۱۰ تسلیم وسوسه شدم و یک domain اختصاصی به آدرس http://afsharm.com ثبت کردم. از این به بعد اطلاعات مربوط به خودم را در اینجا قرار می‌دهم. وبلاگم هم از آدرس قبلی به آدرس http://blog.afsharm.com منتقل شده است. البته این همان وبلاگ اصلی خودم است که فقط آدرسش عوض شده. یعنی اگر از طریق فید مطالب را دنبال می‌کرده‌اید نیاز به تغییر چیزی ندارید. علاوه بر این همه لینک‌های قبلی هم همچنان کار می‌کنند. چون هر ارجاعی به آدرس قبلی وبلاگم به آدرس جدید آن Redirect می‌شود.

محدودیت‌های شدید در استفاده از منابع image/file hosting مجانی، پیش‌بینی محدودیت‌های جدید در راستای محدودیت‌های سه‌گانه اینترنت و اعتبار نسبی domainهای اختصاصی نسبت به آدرس‌های عمومی مثل blogspot از جمله دلایل این مهاجرت بود. مشتاق شنیدن نظرهای دوستان هستم.




2010/12/30

‫پیدا کردن پروژه‌ی خوب در vWorker

مدتی است که در راستای «‫کار پروژه‌ای در سایت‌های Freelance» سایت vWorker.com را به دنبال پروژه‌های برنامه‌نویسی زیر نظر دارم به این امید که بتوانم روی آنها Bid دهم و چیزی برنده شوم. به همین دلیل پروژه‌ها را به دسته‌های زیر تقسیم کردم:


تقسیم بندی

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


کارهای عجیب و غریب و غیر معمول که معمولا با نرم‌افزارهای خاصی قابل انجام هستند. ولی احتمالاً سفارش دهنده نمی‌توانسته یا پولش را نداشته که از نرم‌افزار اصلی استفاده کند.
‫برنامه‌های مربوط به یک platform خیلی خاص مثل facebook یا iPhone
پروژه‌های تقلیدی و clone. کار خاصی که فلان نرم‌افزار یا وب‌سایت مشهور می‌کند، من هم بتوانم بکنم یا این که من هم عین همان را داشته باشم:

کارهایی که نیاز به دانستن یک روش یا الگوریتم خاص دارد و بیشتر شبیه به پروژه‌های دانشجویی هستند:

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

در طول این مدت که vWorker را زیر نظر داشته‌ام به نکاتی پی برده‌ام. هر چند که این نکات در مورد پروژه‌های خوب vWorker زیاد صدق نمی‌کنند اما در مورد بیشتر پروژه‌ها این نکات وجود دارند:

۱- به نظر می‌رسد vWorker شبیه به ادارات و سازمان‌های داخلی خودمان باشد که همیشه درخواست‌های عجیب و غریب دارند و می‌خواهند این درخواست‌ها با زمان و هزینه‌ی خیلی کم انجام شود.

۲- vWorker بیشر برای کسانی مناسب است که همان پروژه‌ها یا برنامه‌ها را قبلاً به نحوی انجام داده و سورس آن را دارند. حالا فقط باید آن را کمی دستکاری کرده و مجدداً بفروشند.

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

۴- بیشتر پروژه‌های خوب vWorker دیتابیسی هستند. یعنی پیچیدگی خیلی خاصی نداشته و مشابه سیستم‌های مالی-اداری خودمان هستند.

۵- هر روز تعداد زیادی پروژه به vWorker اضافه می‌شوند. اگر می‌خواهید با سرعت بیشتری پروژه‌های خوب‌تر را پیدا کنید در دسته‌بندی‌هایی مثل C#‎، ASP.NET وDesktop Applications بیشتر بگردید. چون در آنجا پروژه‌های بهتری وجود دارد. سورت کردن بر اساس تعداد Viewهای یک پروژه یا rating شخص سفارش دهنده هم می‌تواند کمک خیلی خوبی برای پیدا کردن سریع‌تر پروژه‌های بهتر باشد.




2010/12/28

Update Schema in Castle ActiveRecord

NHibernate has a feature named "Schema Update". This feature help updating schema of existing database based on new changes in mapping files. Schema update do not change current data, just changes schema (table, view, ... structure) in an additive manner. Castle ActiveRecord exposes this feature too.

The problem is with NHibernate you have choice for seeing update scripts first and if you were satisfied then do actual update. But in Castle ActiveRecord you must do actual update without any preview of possible changes. This is all because ActiveRecordStarter.UpdateSchema() does not emit NHibernate.SchemaUpdate.Execute's parameters "scriptAction" and "doUpdate" to the user. It calls SchemaUpdate as follow:

updater.Execute(false, true);
As I needed schema update in Castle ActiveRecord with preview update scripts option, I wrote a method for it:
private static IList UpdateSchema(Action action, bool doUpdate)
{
    CheckInitialized();
    ArrayList exceptions = new ArrayList();


    foreach (Configuration config in ActiveRecordMediator.GetSessionFactoryHolder().GetAllConfigurations())
    {
        SchemaUpdate updater = CreateSchemaUpdate(config);

        try
        {
            updater.Execute(action, doUpdate);

            exceptions.AddRange((IList)updater.Exceptions);
        }
        catch (Exception ex)
        {
            throw new ActiveRecordException("Could not update the schema", ex);
        }
    }

    return exceptions;
}

private static void CheckInitialized()
{
    if (!ActiveRecordStarter.IsInitialized)
    {
        throw new ActiveRecordException("Framework must be Initialized first.");
    }
}

private static SchemaUpdate CreateSchemaUpdate(Configuration cfg)
{
    return new SchemaUpdate(cfg);
}


Hope Castle ActiveRecord add an overload to ActiveRecordStarter.UpdateSchema that let seeing update schema scripts before actually doing the update.




2010/12/26

‫رکورد اضافی در NHibernate


من مشکلی با NHibernate دارم که نمی‌دانم آیا بقیه هم این مشکل را با NHibernate یا دیگر ORMها یا حتی ADO دارند یا نه. البته اصل این مشکل در صفحات ASP.NET Webform وجود دارد. مشکل این است که وقتی می‌خواهم یک آیتم را در دیتابیس ذخیره کنم یا حتی وقتی می‌خواهم یک رکورد را روی صفحه نمایش دهم مجبور می‌شوم یک یا چند رکورد اضافی را هم از دیتابیس بخوانم.

به عنوان مثال یک صفحه ASP.NET را به شکل زیر تصور کنید:

protected void btnSave_Click(object sender, EventArgs e) { Company company = new Company() { City = City.Find(drpCity.SelectedValue), Address = txtAddress.Text }; company.Save(); } protected void Search() { IList result = MyCustomSearch.SearchCompanies( City.Find(drpCity.SelectedValue), txtAddress.Text); //display results in GridView }

در صفحه بالا، همه Cityها به طور خودکار به drpCity بایند می‌شوند. سپس با کلیک روی دکمه btnSave یک Company با کمک اطلاعات txtAddress و drpCity ذخیره می‌شود. البته کد بالا با Castle ActiveRecord نوشته شده ولی اصل مشکل با دیگر ORMها همان است. همان طور در متود btnSave_Click مشاهده می‌کنید من مجبور هستم برای ذخیره آبجکت Company یک بار به دیتابیس مراجعه کرده و City مورد نظر را از آن فراخوانی نمایم. در متود Search هم همین اتفاق می‌افتد چون متود SearchCompanies پارامتری از نوع City نیاز دارد.

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


IList SearchCompanies(City city, string address)
{
    var query = from company in ActiveRecordLinq.AsQueryable()
                where City == city
                select company;

    //...
}


این متود را به راحتی می‌توان طوری تغییر داد که به جای City از CityID استفاده کند:


IList SearchCompanies(long cityID, string address)
{
    var query = from company in ActiveRecordLinq.AsQueryable()
                where City.ID == cityID
                select company;

    //...
}




2010/12/24

بی‌توجهی به گزارشات سیستم


یکی از مراحل تولید هر سیستمی بخش گزارشات آن است. با این که در بیشتر سیستم‌ها خصوصاً سیستم‌های مالی و اداری و امثال آنها که پر از Businness هستند، درک و پیاده‌سازی گزارشات بخش مهمی از سیستم را تشکیل می‌دهد، ولی متاسفانه اهمیت کافی به آنها داده نمی‌شود.

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

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




Limitations of LINQ-to-NHibernate

Some applications are using NHibernate 2.1.2 yet. So they are forced to use old LINQ-to-NHibernate that comes with NHibernate 2.1.2 and can't benefit new LINQ provider in NH 3.

There are two annoying problems with old LINQ-to-NHibernate. The first is inheritance related queries: "is" operator can't be used. The second problem is not supporting "distinct". For the first problem I added a read-only formula field based on discriminator column to "hbm" mapping file. After this, a query can use this fake field instead of "is" operator. But for the second problem I didn't find any solution. Possibly I should use ICriteria instead of LINQ-to-NHibernate.

More info: link 1, link 2, link 3.




2010/12/23

محدودیت‌های سه گانه در اینترنت

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

یک: محدودیت دولتی
دولت بنا به دلایل خاص خودش دسترسی به بسیاری از سایت‌های اینترنتی را مسدود کرده. تا زمانی که این سایت‌ها فقط سایت‌ها خبری فارسی و حتی خبری انگلیسی زبان و سایت‌های غیر اخلاقی (نسبت به عرف رایج جامعه ما) بودند نگرانی زیادی وجود نداشت. اما وقتی که دایره حملات گسترش یافت و به جای بستن یک یا چند وبلاگ خاص کل وردپرس (صفحه login یا صفحه tagها) بسته شد و وقتی که ف.ی.ل.ت.ر.ی.ن.گ کور شد و هر نوع search گوگل را که دارای کلمات دو پهلو بودند را هدف قرار داد (مثلا عبارت asp.net error number assembly version 1.xxx را در گوگل جستجو کنید) و وقتی که امکانات اجتماعی مشترک مثل FeedBurner در محاق توقیف فرو رفت، دیگر نمی‌شد نگران نبود. با این محدودیت‌ها استفاده از اینترنت حتی برای کسانی که فقط قصد استفاده از اینترنت برای موارد فنی و علمی را داشتند هم به شدت سخت شده است.

دو: محدودیت‌های بین‌المللی
سایت‌های خارجی خصوصاً آمریکایی هم ما را بی‌نصیب نگذاشته‌اند. روز به روز سرویس دهندگان بیشتری ما را از دایره خارج می‌کنند. یک بار SourceForge نمی‌گذارد پروژه‌ها Open Source را دانلود کنیم. یک بار گوگل جلوی استفاده از Chrome را می‌گیرد. یک بار فلان Data Center که اتفاقاً تعدادی سایت برنامه‌نویسی معروف را هم میزبانی می‌کند جلوی IPها ایرانی را می‌گیرد و همین طور الی آخر. توی خیلی از سایت‌ها موقع ثبت نام از شما قول می‌گیرند که نکند یک وقت ایرانی باشید! بیشتر سایت‌ها هم که در لیست کشورهایشان اصلاً اسم ایران را ندارند. آن وقت ما بیچاره‌ها مدام باید IPمان را از این و اون مخفی کنیم که مبادا هویت‌مان معلوم شود. هر جا هم خواستیم عضو شویم خودمان را اماراتی، عراقی یا افغانستانی معرفی کنیم.

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


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




2010/12/22

خاطرات شاد مخصوص یلدا


دوست خوبم آقای مجید آواژ (وبلاگ بهساد) من را دعوت کرده به یک بازی وبلاگی به نام «خاطراتی برای یلدا» که قرار است ذکر چند خاطره‌ی شاد مخصوص شب یلدا باشد. هر چند که الان یک شب از یلدا گذشته اما این هم سهم من از این بازی:



آتاری

یکی از زنده‌ترین خاطرات شاد دوران کودکی من مربوط می‌شود به بازی با آتاری. حول و حوش سال ۱۳۶۴ یا ۱۳۶۵ من و برادرهام می‌مردیم برای یک دقیقه آتاری بازی خصوصاً دو مدل بازی هواپیما، زیر دریایی و دزد و پلیس. اون موقع هر چقدر پول توجیبی و توان التماس کردن داشتیم را جمع می‌کردیم تا بتوانیم یک شب آتاری کرایه کنیم با دسته گوشت کوبی یا دسته خلبانی! فیلم‌های ۳۲ لبه یادتون می‌یاد؟ آتاری و ساعت دیجیتال اولین برخوردهای من با دنیای کامپیوتر بودند و فکر می‌کنم از همون جا بود که افتادم تو خط کامپیوتر. البته چند وقت بعد بمباران‌های هوایی شدید غرب کشور شروع شد و روزگارمان را سیاه کرد.


نمره ۱۰

در دوران دانشگاه برای ما که نرم‌افزاری بودیم درس آمار و احتمال درس کم اهمیتی بود و تقریباً پیش‌نیاز هیچ درس دیگه‌ای نبود. من هم چون با ریاضیات کلاسیک به شدت مشکل داشتم این درس را گذاشته بودم برای آخرین ترم. آخر ترم امتحان خیلی سختی بزگرار شد و من که فکر می‌کردم بتوانم نمره قبولی بگیرم ۳ گرفتم! ۷ نمره زیر نمره قبولی. التماس و گریه و زاری به استاد هم هیچ افاقه‌ای نکرد. فکر می‌کردم حسابی بدبخت شده‌ام. چون تمام برنامه‌های سربازی، کار و خونه‌ی اجاره‌ای با افتادن اون درس لعنتی به هم می‌خورد. قرار شده بود استاد مربوطه نمرات قطعی را چند روز دیگر اعلام کند. روز اعلام نمرات به دانشکده ریاضی رفتم و با کمال ناباوری دیدم نمره‌ها رفته روی نمودار و نمره من ۱۰ شده بود! داشتم از خوشحالی بال در می‌آوردم. اون روز فقط توی دانشگاه راه می‌رفتم و به همه می‌گفتم که چه *ر شناسی آورده‌ام! اون روز دقیقاً اول بهمن ۱۳۸۱ بود. هنوز هم که هنوزه روزهای اول هر ماه را به افتخار اون استاد بامرام جشن می‌گیرم. استاد باز هم دمت گرم!


رژه

بهمن ۱۳۸۲ در پادگان ولیعصر تبریز در حال گذراندن دوران آموزشی بودم. تقریباً ۴۰ روز از شروع دوره گذشته بود و بچه‌های گروهان ۱۰۱ هم رژه را خوب یاد گرفته بودند و هم حسابی با هم هماهنگ شده بودند. تمرینات بدنی زیاد ۴۰ روز گذشته و منظم شدن ساعات خواب و غذا هم باعث شده بود بدنم سرحال بیاد و حسابی نرم بشه. شاید برای خیلی‌ها باور کردنش سخت باشد اما رژه‌های روزهای آخر آموزشی جز شادترین لحظات آن دوران من حساب می‌شد. وقتی که همه افراد گروهان با اون ژ-۳ های یک تنی هماهنگ با طبل کوچک و بزرگ پا بر زمین می‌کوبیدند زمین می‌لرزید. لرزش زمین، نظم و انضباط فوق‌العاده، اسلحه‌های ژ-۳ و آمادگی بدنی چنان حس قدرتی در آدم ایجاد می‌کرد که فکر می‌کرد همین الان می‌تواند با هر ارتش دیگری در دنیا بجنگد. البته ناگفته نماند که ما نیروی انتظامی بودیم نه ارتش!


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




2010/12/20

جمع‌های برنامه‌نویسی

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

متاسفانه چنین جمع‌هایی در حوزه برنامه‌نویسی و توسعه‌ی نرم‌افزار کم هستند و اگر هم هستند در موضوعات خیلی پراکنده‌ای کار می‌کنند. معمولاً همکارات داخل شرکتی هم هر کدام روی یک بخش متفاوت کار می‌کنند و نمی‌توانند جمع‌هایی راجع به مثلاً C#‎، Software Design، ORM و… تشکیل دهند یا اگر هم بتوانند، افراد جمع بیش از دو سه نفر نخواهد بود.

یکی از راه‌های جایگزینی که جدیداً برای این مشکل پیدا کرده‌ام، حضور مستمر در StackOverflow است. کاربران این سایت می‌توانند تعدادی tag مثل nhibernate، tfsbuild یا log4net را به عنوان tagهای مورد علاقه اضافه کرده و سوال و جواب‌های آنها را به طور مداوم زیر نظر داشته باشند. به این ترتیب می‌توانند نظرات و تجارب آدم‌های مختلف را دیده و در پاسخگویی و نظر دهی شرکت کنند. علاوه بر این سایت StackOverflow جدیداً بخش جدیدی به عنوان chat به سایت خودش اضافه کرده که آن هم می‌تواند ذره‌ای از این خلأ تنهایی تکنولوژیک را کم کند.




2010/12/18

‫IEnumerable و IQueryable

اگر می‌خواهید از یک کوئری LINQ به عنوان خروجی یک متود استفاده کنید دو راه برای آن وجود دارد. یکی آن که خروجی متود را از نوع IEnumerable تعریف کنیم و یکی دیگر آن که خروجی آن را از نوع IQueryable تعریف کنیم. استفاده از IEnumerable به معنی پایین آمدن Performance است. به همین دلیل بهتر است از IQueryable استفاده کنیم. نکته‌ی جالب‌تری که فهمیدم این است که اگر از IEnumerable به عنوان خروجی متود استفاده شود دیگر نمی‌توان از متودهایی نظیر Skip و Take که در Data Pagination استفاده زیادی دارند استفاده کرد. به عنوان مثال به کد زیر دقت کنید:
IEnumerable MakeQuery()
{
  var query = from m in session.Linq()
              select m;
  return query;
}

List m1()
{
  return MakeQuery()
    .Skip(10)
    .Take(20)
    .ToList();
}
توابع Skip و Take در متود m1 بی‌تاثیر هستند. البته نه این که عمل نمی‌کنند بلکه باعث می‌شوند کل دیتا از منبع مورد نظر، که در مورد من Linq-to-NHibernate و دیتابیس بود، فراخوانی شوند نه آن که صرفاً آن بخش خاص بازیابی شوند.




2010/12/16

‫استفاده از سورس‌های 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های متعدد ندارند و لینک آنها را به راحتی می‌توان از طریق ایمیل و غیره به این ور و اون ور فرستاد.




2010/12/14

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

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

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

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

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




2010/12/12

‫مشکل با FeedBurner

مدت خیلی زیادی بود که نمایشگر فید وبلاگم از کار افتاده بود. با Google Reader هم نمی‌شود فید آن را مشترک شد. حتی با فیدهای دیگری هم که قبلاً در Google Readerم هم موجود بود مشکل پیدا کرده بودم. علت موضوع را تا حد زیادی می‌دانستم اما نمی‌دانستم که قابل درمان است. دیروز به طور اتفاقی جستجوی کوچکی در این باره کردم و راه حل را در «داناترین» و «آر2جی بلاگ» پیدا کردم. به همین جهت در تنظیمات وبلاگم آدرس http://feeds.feedburner.com/afsharm را با http://feeds2.feedburner.com/afsharm عوض کردم. امیدوارم مشکلی برای فیدخوان‌ها به وجود نیاید.




‫داستان بی‌سوادی ما - ۶: Application Pool

یکی از مشکلات عجیب و غریب ما این بود که یکی از پروژه‌های ما مشکلات عجیبی با IIS داشت. این پروژه (الف) از پروژه‌ی دیگری (ب) مشتق شده بود. یعنی هر آن چه که در پروژه‌ی «ب» موجود بود در پروژه‌ی «الف» هم بود. پروژه‌ی «ب» هیچ مشکلی نه در ASP.NET Development Server و نه در IIS نداشت. اما پروژه‌ی «الف» در ASP.NET Development Server درست کار می‌کرد ولی در IIS نه.

این موضوع باعث اختلاف نظرهای زیادی شده بود. تا این که یک روز فهمیدم مشکل پروژه‌ی «الف» کجاست. علت، مقایسه‌ی آبجکت‌ها در حافظه بدون استفاده از ID آنها بود. این مقایسه در ASP.NET Development Server درست کار می‌کرد ولی در IIS درست کار نمی‌کرد. بعد از رفع مشکل هنوز این سوال برایم وجود داشت که چرا پروژه‌ی «ب» دچار چنین مشکلی نشده بود؟

یک روز که دنبال چیز دیگری در IIS بودم متوجه شدم که هر کدام از این پروژه‌ها از یک Application Pool مختلف برای کار خود استفاده می‌کنند. پروژه‌ی «ب» از Classic .NET AppPool استفاده می‌کرد ولی پروژه‌ی «الف» از DefaultAppPool. فرق این دو هم فقط در Pipline بود. اولی Classic بود و دومی Integrated. محض امتحان یک بار Application Pool پروژه‌ی «الف» را به Classic عوض کردم و آن مقایسه‌ای آبجکتی را دوباره به حالت بدون ID برگرداندم. در کمال ناباوری مشکل اولیه‌ی پروژه‌ی «الف» حل شد!

در واقع مشکل پروژه‌ی «الف» را می‌شد با درک بهتری از Pipeline زودتر کشف کرد که به علت بی‌سوادی و بی‌اطلاعی این موضوع اتفاق نیفتاده بود. البته الان می‌دانم علت خرابی کار Pipeline بوده ولی هنوز هم درک نمی‌کنم چرا.




2010/12/10

‫شرکت‌های bug دوست

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

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

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




2010/12/08

Web Development Server and IIS

I am using "ASP.NET Development Server" with Visual Studio 2010 Ultimate x64 on a Windows Server 2008 R2 x64 machine. Development Server is my primary development and debug my ASP.NET applications. After my work is done, the website moves to an IIS 7.5 on a Windows Server 2008 R2 x64 (same machine) with "DefaultAppPool".

I was used to think that an application's behavior is as same as in both "ASP.NET Development Server" and "IIS". Both recently realized they are not as same as I think. I found 3 situations that they behave differently:

1. Server.MapPath behaved differently between them. Path that returned from one was different from other one. More detail available here.

2. Object comparison in LINQ-to-Object queries with comparing only objects themselves is not possible in IIS, this comparison should be done with comparing object's Ids.

3. Our data access layer is implemented via Castle ActiveRecord. In an arbitrary method properties of an entity was updating without calling its .Save() method. Despite I agree this is a bug itself, the method was working properly in ASP.NET Development Server but was not working in IIS.


I'm not the only person that think ASP.NET Development Server and IIS behaves differently. Other people like this think like me.

At this moment I'm curios about How Application Pool affects IIS and what is Application Pool of ASP.NET Development Server. Additionally Pipeline mode may be a cause of many of this problems. Pipeline mode in IIS 6 and below was classic that means they was using ISAPI but in IIS 7 and above a new Pipeline has been emerged. This new Pipeline is named "Integrated" and do not use ISAPI.




2010/12/07

برون‌سپاری خدمات تخصصی - ۴

یکی دیگر از مشکلات این موضوع، استاندارد نبودن و بی‌نظمی کارها در شرکت‌هاست. این مشکل بیشتر گریبان‌گیر نیروی کار بیرون شرکتی است که قرار است در داخل یک شرکت خدمات تخصصی ارائه دهد.

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

به عنوان دیگر مصادیق می‌توان به موضوعات دیگری نیز اشاره کرد: نبود مستندات کافی، عدم استفاده‌ی صحیح معماری‌های رایج، استفاده‌ی نامتعارف از فناوری‌ها و روش‌های مرسوم، عدم استفاده از نرم‌افزارهای Source Control، نام‌گذاری‌های نامناسب در سورس کد، استفاده از فناوری‌های متنوع برای یک کار یکسان مثل استفاده هم‌زمان از ADO و EF، NHibernate، SQL Server، MySQL و غیره در یک پروژه‌ی متوسط و…

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


توجه:
این نوشته جز سری نوشته‌های «برون سپاری خدمات تخصصی» می‌باشد.




2010/12/06

‫NHibernate 3 منتشر شد

بالاخره NHibernate 3 هم بعد از چند نسخه آلفا و بتا به نسخه نهایی رسید. بخشی از مهم‌ترین خصوصیات NH 3 عبارتند از:

۱- LINQ-to-NHibernate جدید و کامل‌تر
۲- مبتنی بر ‎.Net Framework 3.5
۳- Column lazy loading
۴- API جدید QueryOver

برای دانلود NH 3 به این آدرس و برای دیدن فهرست کامل تغییرات نسخه جدید به این آدرس مراجعه کنید.




2010/12/04

برون‌سپاری خدمات تخصصی - ۳

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

به عنوان مثال: کارفرما منظورش از Component یک چیز است ولی برنامه‌نویسان شرکت برداشت دیگری از Component دارند. مدیر پروژه منظورش از تست، Integration Test است در حالی که منظور برنامه‌نویس Unit Test است. کارمند داخل شرکتی تفاوت زیادی بین Bug و Feature قائل نمی‌شود در حالی که این دو برای نیروی بیرون شرکتی تفاوت زیادی با هم دارند.

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

به هر حال نبود ادبیات مشترک هم ترس طرفین را نسبت به کار با یکدیگر زیاد می‌کند، هم دوباره کاری را زیاد می‌کند و هم هزینه‌ی کار را بالا می‌برد.


توجه:
این نوشته جز سری نوشته‌های «برون سپاری خدمات تخصصی» می‌باشد.




2010/12/03

برون‌سپاری خدمات تخصصی - ۲

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

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

نتیجه‌ی این مسائل این می‌شود که کارفرما ترجیح می‌دهد کار تخصصی‌اش را به فردی کم تجربه‌تر ولی آشناتر بسپارد تا به فردی با تجربه‌تر ولی ناآشنا.


توجه:
این نوشته جز سری نوشته‌های «برون سپاری خدمات تخصصی» می‌باشد.




2010/12/02

آنچه به جایی نرسد فریاد است

چیزی که این روزها به شدت در اطرافم قابل لمس است، نبود عدالت و ایضاً نبود نظم است. روزهای چهارشنبه و پنج‌شنبه ۱۰ و ۱۱ آذر ۱۳۸۹ به علت آلودگی هوا تعطیل اعلام شده است. اما تعطیلی برای چه کسانی؟ برای از ما بهتران، برای کسانی که در بخش نازپرورده‌ی دولتی کار می‌کنند. من نمی‌دانم این چه جور تعطیلی است که فقط برای دولتی‌ها تعطیل است. آیا ریه‌ی کارمندان بخش خصوصی فیلتر سرخود دارد؟ آیا خصوصی‌ها دل ندارند که سه روز تعطیلی را به مسافرت بروند؟ آیا خصوصی‌ها کار و گرفتاری ندارند که بخواهند از تعطیلات استفاده کرده و به آن برسند؟ آیا گردانندگان بخش خصوصی هم روی چاه نفت نشسته‌اند که بخواهند از آن بذل و بخشش شاهانه کرده و کارمندانش را به تعطیلات بفرستند؟ واقعاً با این شرایط است که ملت انتظار دارند اینقدر شاهد مهاجرت نیروی ماهر و فرار مغزها نباشیم؟