نظرات مطالب
EF Code First #7
سلام، از اینجا می‌تونید دریافت کنید: (^)
مطالب
NOSQL قسمت اول
  در این پست نگاهی کلی به ویژگی‌های پایگاه‌های داده NOSql خواهیم داشت و با بررسی تاریخچه و دلیل پیدایش این سیستم‌ها آشنا خواهیم شد.
  با فراگیر شدن اینترنت در سال‌های اخیر و افزایش کاربران ، سیستم‌های RDBMS جوابگوی نیازهای برنامه‌نویسان در حوزه‌ی وب نبودند زیرا نیاز به نگهداری داده‌ها با حجم بالا و سرعت خواندن و نوشتن بالا از جمله نقط ضعف سیستم‌های RDBMS میباشد ، چرا که با افزایش شدید کاربران داده‌ها اصولا به صورت منطقی ساختار یکدست خود را جهت نگه‌داری از دست می‌دهند و به این ترتیب عملیات نرمال سازی منجر به ساخت جداول زیادی می‌شود که نتیجه آن برای هر کوئری عملیات Join‌های متعدد می‌باشد که سرعت خواندن و نوشتن را به خصوص برای برنامه‌های با گستره‌ی وب پایین می‌آورد و مشکلات دیگری در سیستم‌های RDBMS که ویژگی‌های سیستم‌های NoSql مشخص کننده آن مشکلات است که در ادامه به آن می‌پردازیم.
طبق تعریف کلی پایگاه داده NOSql عبارت است از:
نسل بعدی پایگاه داده (نسل از بعد RDBMS ) که اصولا دارای چند ویژگی زیر باشد:
۱- داده‌ها در این سیستم به صورت رابطه‌ای (جدولی)  نمی‌باشند
۲-داده‌ها به صورت توزیع شده نگهداری می‌شوند.
۳-سیستم نرم‌افزاری متن باز می‌باشد.
۴-پایگاه داده مقیاس پذیر به صورت افقی می‌باشد(در مطالب بعدی توضیح داده خواهد شد.)

  همان‌گونه که گفته شد این نوع پایگاه داده به منظور رفع نیاز‌های برنامه‌های با حجم ورود و خروج داده بسیار بالا  (برنامه‌های مدرن وب فعلی) ایجاد شدند.
شروع کار پیاده‌سازی این سیستم‌ها در اوایل سال ۲۰۰۹ شکل گرفت و با سرعت زیادی رشد کرد و همچنین ویژگی‌های کلی دیگری نیز به این نوع سیستم اضافه شد.
که این ویژگی‌ها عبارتند از:
  • Schema-free : بدون شَما ! ، با توجه به برنامه‌های وبی فعلی ممکن است شمای نگه‌داری داده‌ها ( ساختار کلی ) مرتبا و یا گهگاهی تغییر کند. لذا در این سیستم‌ها اصولا داده‌ها بدون شمای اولیه طراحی و ذخیره می‌شوند. ( به عنوان مثال می‌توان در یک سیستم که مشخصات کاربران وارد سیستم می‌شود برای یک کاربر یک سری اطلاعات اضافی و برای کاربری دیگر از ورود اطلاعات اضافی صرف‌نظر کرد ، و در مقایسه با RDBMS به این ترتیب از ورود مقادیر Null و یا پیوند‌های بیمورد جلوگیری کرد.
    کنترل اطلاعات الزامی توسط لایه سرویس برنامه انجام می‌شود. ( در زبان جاوا توسط jsr-303 و یاBean Validation ها)
  • easy replication support : در این سیستم ، نحوه‌ی گرفتن نسخه‌های پشتیبان و sync بودن نسخه‌های مختلف بسیار ساده و سر راست می‌باشد و سرور پایگاه داده به محض عدم توانایی خواندن و یا نوشتن از روی دیسک سراغ نسخه‌ی پشتیبان می‌رود و آن نسخه را به عنوان نسخه‌ی اصلی در نظر می‌گیرد.
  • Simple API : به دلیل متن‌باز بودن  و فعال بودن Community این سیستم‌ها API‌های ساده و بهینه‌ای برای اکثر زبان‌های برنامه‌نویس محبوب ایجاد شده است که در پست‌های بعدی با ارائه مثال آنها را بررسی خواهیم کرد.
  • eventually consistent : در سیستم‌های RDBMS که داده‌ها خاصیت ACID را ( در قالب Transaction) پیاده می‌کنند ، در این سیستم‌های داده‌ها در وضعیت BASE قرار دارند که سرنام کلمات Basically Available ، Soft State ، Eventual Consistency  می‌باشد.
  • huge amount of data: این سیستم‌ها به منظور کار با داده‌های با حجم بالا ایجاد شده‌اند ، یک تعریف کلی می‌گوید اگر مقدار داده‌های نگهداری شده در پایگاه‌های داده برنامه شما ظرفیتی کمتر از یک ترابایت داده دارد از پایگاه داده RDBMS استفاده کنید واگر ظرفیت آن از واحد ترابایت فراتر می‌رود از سیستم‌های NOSql استفاده کنید.
  به طور کلی پایگاه داده‌ای که در چارچوب موارد ذکر شده قرار گیرد را می‌توان از نوع NoSql که سرنام کلمه (Not Only SQL ) می‌باشد قرار داد. تاکنون پیاده‌سازی‌های زیادی از این سیستم‌ها ایجاد شده است که رفتار و نحو‌ه‌ی نگه‌داری داده‌ها ( پرس‌وجو ها) در این سیستم‌ها با یکدیگر متفاوت می‌باشد.

  جهت پیاده سازی پایگاه داده با این سیستم‌ها تا حدودی نگرش کلی به داده‌ها و نحوه‌ی چیدمان آنها تغییر می‌کند ، به صورت کلی مباحث مربوط به normalization و de-normalization و تصور داده‌ها به صورت جدولی کنار می‌رود.
  سیستم NoSql به جهت دسته‌بندی نحوه‌ی ذخیره‌سازی داده‌ها و ارتباط بین آنها به ۴ دسته کلی تقسیم می‌شود که معرفی کلی آن دسته‌بندی‌ها موضوع مطلب بعدی می‌باشد. 
مطالب
بررسی Bad code smell ها: میراث رد شده

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

public class DiscountCalculator 
{ 
    protected decimal CalculateGeneralDiscount() 
    { 
        // calculate general discount 
        return 0; 
    } 
    protected decimal AddSpecificDiscount(decimal baseDiscount) 
    { 
        // add specific discounts to base discount 
        return 0; 
    } 
    protected virtual decimal GetFinalDiscount() 
    { 
        var baseDiscount = CalculateGeneralDiscount(); 
        var addedDiscount = AddSpecificDiscount(baseDiscount); 
        return addedDiscount; 
    } 
}
بعد از مدتی نیاز می‌شود که افراد حقیقی از نرم افزار استفاده کرده و خرید نمایند و این مکانیزم تخفیف برای آن‌ها نیز اعمال شود. توسعه دهنده بعد از بررسی به این نتیجه می‌رسد که تنها تفاوت این مکانیزم با مکانیزم قبلی، متد AddSpecificDiscount است که باید برای اشخاص حقیقی بازنویسی شود. این توسعه دهنده تصمیم می‌گیرد برای استفاده دوباره از کد موجود در کلاس DiscountCalculator، کلاس مربوط به اشخاص حقیقی را از آن ارث ببرد. که نتیجه به صورت زیر خواهد بود:
public class PersonDiscountCalculator : DiscountCalculator 
{ 
    private decimal AddSpecificDiscountForPerson(decimal baseDiscount) 
    { 
        // calculate base discount for person 
        return 0; 
    } 
    protected override decimal GetFinalDiscount() 
    { 
        var baseDiscount = CalculateGeneralDiscount(); 
        var added = AddSpecificDiscountForPerson(baseDiscount); 
        return added; 
    } 
}

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

روش‌های اصلاح این نوع کد بد بو 

1) زمانیکه رابطه ارث بری هیچ معنایی ندارد، می‌توان به جای استفاده از ارث بری، شیء مربوط به کلاس پدر را ایجاد و در بدنه کلاس فرزند از آن استفاده کرد. مثلا برای فراخوانی متدها یا دسترسی به خصوصیت‌ها (مثال ذکر شده در این دسته نیست).
2) زمانیکه رابطه منطقی وجود داشته باشد، ولی اعضای اضافی کلاس پدر، به فرزند به ارث برسند، راه حل معمولا در جدا کردن کلاس پدر و ایجاد یک کلاس جدید پدر برای مصرف مورد نظر است.  
در مثال مطرح شده رابطه منطقی بین کلاس‌ها وجود دارد؛ ولی نه به شکلی که پیاده سازی شده است. یکی از راه‌های مناسب برای رفع چنین مشکلی، ایجاد یک کلاس پدر مشترک (در اینجا DiscountCalculator) و انتقال منطق‌های مربوطه به آن و ارث بری کردن تک تک کلاسها از آن است.  
public abstract class DiscountCalculator 
{ 
    protected decimal CalculateGeneralDiscount() 
    { 
        // calculate general discount 
        return 0; 
    } 
    protected abstract decimal AddSpecificDiscount(decimal baseDiscount); 
    protected virtual decimal GetFinalDiscount() 
    { 
        var baseDiscount = CalculateGeneralDiscount(); 
        var addedDiscount = AddSpecificDiscount(baseDiscount); 
        return addedDiscount; 
    } 
}

کلاس DiscountCalculator به عنوان کلاس پایه برای محاسبات تخفیف تعریف شده و کلاس‌های مربوط به شرکت و شخص از آن ارث بری می‌کنند. به این صورت که محاسبات کلی تخفیف‌ها در کلاس پایه و محاسبات مربوط به افزودن تخفیف‌های خاص در کلاس‌های فرزند انجام می‌شود (با فرض این که محاسبات مربوط به افزودن تخفیف‌های خاص تفاوت دارند).   
public class CompanyDiscountCalculator: DiscountCalculator 
{ 
    protected override decimal AddSpecificDiscount(decimal baseDiscount) 
        { 
            // add some customer specific discounts to base discount 
            return 0; 
        } 
    } 
    public class PersonDiscountCalculator : DiscountCalculator 
    { 
        protected override decimal AddSpecificDiscount(decimal baseDiscount) 
        { 
            // calculate base discount for person 
            return 0; 
        } 
}

جمع بندی 

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

نظرات مطالب
ASP.NET MVC #18
- نیازی نیست تمام متدهای RoleProvider دات نت پیاده سازی شوند. برای یک برنامه پیاده سازی دو متد IsUserInRole، GetRolesForUser کافی است. 
- سپس دو کلاس Role و User را باید تعریف کنید. این دو رابطه many-to-many با هم دارند؛ یعنی هر کدام با یک ICollection به دیگری ارتباط پیدا می‌کنند. سپس این دو کلاس را در کلاس Context برنامه مطابق معمول توسط DbSetها در معرض دید EF قرار می‌دهید. مابقی آن کارکردن معمولی با این دو جدول اضافه شده به برنامه است:
    public class EfRolesService : IRolesService
    {
        readonly IUnitOfWork _uow;
        readonly IDbSet<Role> _roles;
        public EfRolesService(IUnitOfWork uow)
        {
            _uow = uow;
            _roles = _uow.Set<Role>();
        }

        public IList<Role> FindUserRoles(int userId)
        {
            var query = from role in _roles
                        from user in role.Users
                        where user.Id == userId
                        select role;

            return query.OrderBy(x => x.Name).ToList();
        }

        public string[] GetRolesForUser(int userId)
        {
            var roles = FindUserRoles(userId);
            if (roles == null || !roles.Any())
            {
                return new string[] { };
            }

            return roles.Select(x => x.Name).ToArray();
        }

        public bool IsUserInRole(int userId, string roleName)
        {
            var query = from role in _roles
                        where role.Name == roleName
                        from user in role.Users
                        where user.Id == userId
                        select role;
            var userRole = query.FirstOrDefault();
            return userRole != null;
        }
    }
و در این حالت CustomRoleProvider به صورت زیر خواهد بود. در این روش فرض شده حین لاگین، user.Id در FormsAuthentication.SetAuthCookie تنظیم می‌شود؛ یعنی userName در این RoleProvider به id آن تنظیم شده:
    public class CustomRoleProvider : RoleProvider
    {
        public override bool IsUserInRole(string username, string roleName)
        {
            // Since the role provider, in this case the CustomRoleProvider is instantiated by 
            // the ASP.NET framework the best solution is to use the service locator pattern. 
            // The service locator pattern is normally considered to be an anti-pattern but 
            // sometimes you have to be pragmatic and accept the limitation on the framework 
            // that is being used (in this case the ASP.NET framework).

            var rolesService = ObjectFactory.GetInstance<IRolesService>();
            return rolesService.IsUserInRole(username.ToInt(), roleName);
        }

        public override string[] GetRolesForUser(string username)
        {
            var rolesService = ObjectFactory.GetInstance<IRolesService>();
            return rolesService.GetRolesForUser(username.ToInt());
        }
// مابقی نیازی نیست پیاده سازی شوند
مطالب
متد LastOrDefault در EF
اگر بخواهیم اولین رکورد از یک جدول را توسط EF درخواست نماییم از متد Firstیا FirstOrDefault استفاده می‌شود. برای مثال واکشی اولین رکورد از جدول Student به صورت زیر است:
 var student=context.Students.FirstOrDefault();
در این حالت اولین رکورد از جدول student واکشی می‌شود و اگر رکوردی موجود نباشد یک مقدار null بازگشت داده می‌شود.
حال اگر بخواهید به جای اولین رکورد آخرین رکورد را واکشی نمایید چطور؟ برای یافتن آخرین رکورد در لیست‌ها ی Generic و کلا لیست‌های Enumerable از متد LastOrDefault استفاده می‌شود. با این حال این متد توسط Entity Framework پشتیبانی نمی‌شود و در صورتی که از کد زیر استفاده کنید برنامه با خطا متوقف خواهد شد:
 var student=context.Students.LastOrDefault();
دو راه حل برای رفع این مشکل به ذهن می‌رسد:
روش اول: می‌توان خروجی را ابتدا به یک نوع Enumerable مانند List تبدیل کرد و سپس از متد LastOrDefault استفاده کرد. کد زیر را در نظر بگیرید:
 var student=context.Students.ToList().LastOrDefault();
در کد بالا ابتدا رکوردهای جدول Student از درون بانک اطلاعات به صورت کامل واکشی شده و سپس رکورد آخر از میان آنها جدا می‌شود. این حالت در حالی که رکوردهای کمی در جدول وجود داشته باشد روش بدی به حساب نمی‌آید ولی اگر تعداد رکورد‌ها زیاد باشد (اکثر مواقع نیز به همین شکل است) روش مناسبی نمی‌باشد و باعث کندی برنامه می‌شود.

 روش دوم: با توجه به اینکه تنها به یک رکورد (آخرین رکورد) نیاز داریم بهتر است یک رکورد هم واکشی شود. در این روش برای اینکه بتوان به آخرین رکورد رسید ابتدا رکورد‌های جدول را به صورت نزولی مرتب می‌کنیم و سپس از متد FirstOrDefault برای واکشی آخرین رکورد استفاده می‌نمایید. برای مثال: 
 var student=context.Students.OrderByDescending(s=>s.Id).FirstOrDefault();
در کد بالا ابتدا رکوردها را بر اساس فیلد مورد نظر به صورت نزولی مرتب کرده ایم(در نظر داشته باشید عملیات مرتب سازی را می‌توان بر اساس فیلدی که مورد نظر است انجام داد) و پس از آن با توجه به اینکه رکوردها به صورت نزولی مرتب شده اند و رکورد آخر به اول منتقل شده است از متد FirstOrDefault جهت دسترسی به آخرین رکورد که در حال حاضر اول لیست رکورد‌ها است استفاده شده است. سرعت این روش به مراتب از روش اول بیشتر می‌باشد. برای بالا رفتن سرعت مرتب سازی در جداول بزرگ نیز می‌توان از تدابیری همچون Index گذاری بر روی فیلدها در DataBase استفاده کرد(با توجه به فیلدی که قرار است مرتب سازی بر اساس آن انجام شود).
 
نظرات مطالب
مدیریت دانلود‌های همزمان از یک سایت و بحث تایم آوت
در این مورد خیر.
اگر سرور یا حتی برنامه برای این نوع حملات آماده نشده باشند، بله. این روش‌ها می‌تونه عملیات سایت رو مختل کنه. البته هدف من فقط دریافت فید از یک سایت مادر بود :)
مطلبی رو چند وقت پیش در سایت آقای Omar AL Zabir دیدم که در همین ارتباط بود. نحوه ایجاد این نوع حملات و نحوه دفاع توسط یک برنامه هوشمند که برای این موارد آماده شده:
مشاهده مطلب:
http://msmvps.com/blogs/omar/archive/2007/03/24/prevent-denial-of-service-dos-attacks-in-your-web-application.aspx
مثالی هم که در سایت ایشون برای حمله عنوان شده عملا با پیش فرض‌های دات نت (حداکثر 2 کانکشن همزمان) کار خاصی رو انجام نمیده و نهایتا timeout خواهند گرفت، مگر اینکه ...