آشنایی با اصول .S.O.L.I.D (بخش اول - SRP):


با عرض سلام و احترام.
پیشاپیش از شما دوست عزیز و گرامی، بابت وقتی که برای مطالعه ی این مطلب خواهید گذاشت، سپاسگزارم.
تقاضا دارم، در صورت مشاهده ی اشتباه متنی یا محتوایی، به اینجانب اطلاع دهید تا (ضمن کمک به یادگیری بنده) در اسرع وقت برای اصلاح متن اقدام نمایم.
شماره ی تماس:
09215149218
نشانی پست الکترونیکی:
RezaQadimi.ir@Gmail.com
آدرس سایت ها:
https://Reza-Qadimi.ir - https://WannaDate.ir

هدف من در این مقاله، آشنایی شما با اولین اصل از اصول .S.O.L.I.D، یعنی SRP یا Single Responsibility Principle می باشد.


اصل SRP را می توان با یکی از این دو روش توصیف کرد:

  1. تک وظیفه بودن: هر کلاس و یا متدی، باید صرفا و فقط یک مسئولیت داشته باشد.
  2. وجود یک دلیل برای تغییر: هر کلاس یا متدی، باید صرفا و فقط یک دلیل برای تغییر داشته باشد.

رعایت اصل SRP، در کاهش پیچیدگی کد، و همینطور کاهش هزینه ی نگهداری و توسعه آن تاثیر مثبتی دارد.

تعدادی از مزایای رعایت این اصل، عبارتند از:

  1. کاهش وابستگی.
  2. کاهش پیچیدگی کد.
  3. افزایش امکان تست پذیری.
  4. افزایش خوانایی، و کاهش هزینه ی توسعه و نگهداری آن.
  5. امکان استفاده ی مجدد از کدهای نوشته شده (رعایت: DRY Principle)، و کاهش احتمال بروز خطا و نیز کاهش هزینه ی برطرف کردن خطاها.

به کد زیر توجه کنید:

public class BankAccount : object
{
        public BankAccount() : base()
        {
        }

        public string AccountNumber { get; set; }

        public decimal AccountBalance { get; set; }

        public decimal CalculateInterest()
        {
                // calculate interest
                // return result...
        }
}


در این مثال کلاس "BankAccount"، دارای دو پراپرتی یا ویژگی مربوط به حساب است، و علاوه بر آن وظیفه ی محاسبه ی نرخ سود هر حساب را هم بر عهده دارد.

حال به تعدادی از تغییراتی که ممکن است، در آینده به وجود بیاید را با هم بررسی میکنیم:

  1. پراپرتی ای به نام "AccountHolderName" اضافه کنید.
  2. قوانین دیگری را، جهت محاسبه ی نرخ سود اضافه کنید.

این موارد کاملا با هم متفاوت هستند! مورد اول در ویژگی های مربوط به "حساب" تغییر ایجاد میکند، و مورد دوم در (رفتار) نحوه ی محاسبه ی "نرخ سود"! این بدان معناست که ما دو دلیل کاملا مختلف، برای تغییر یک کلاس داریم (که نشان دهنده ی عدم رعایت اصل SRP است).

حال بیایید این کد را، با رعایت اصل SRP پیاده سازی کنیم:

public interface IBankAccount
{
        string AccountNumber { get; set; }

        decimal AccountBalance { get; set; }
}


public interface ISavingAccount
{
        decimal CalculateInterest();
}


public class BankAccount : object, IBankAccount
{
        public BankAccount() : base()
        {
        }

        public string AccountNumber { get; set; }

        public decimal AccountBalance { get; set; }
}


public class SavingAccount : object, ISavingAccount
{
        public SavingAccount() : base()
        {
        }

        public decimal CalculateInterest(IBankAccount account)
        {
                 // calculate interest rate;
                 // return interest rate;
        }
}


حال کلاس "BankAccount" ما، صرفا و فقط مسئولیت ویژگی های مربوط به "حساب بانکی" را بر عهده دارد.

اگر در هر زمانی، بخواهیم قوانین business ی جدیدی برای محاسبه ی نرخ سود اضافه کنیم، نیازی به تغییر کلاس "BankAccount" نخواهیم داشت. همینطور هر زمان که بخواهیم پراپرتی جدیدی به کلاس "BankAccount" اضافه کنیم (مثلا AccountHolderName) نیازی به تغییر کلاس "SavingAccount" نداریم.


پی نوشت: در مقاله ی بعد، به بررسی اصل Open/Closed Principle خواهیم پرداخت.


معرفی:
رضا قدیمی هستم. برنامه نویس و دانش آموزِ حوزه ی وب، بسیار مشتاق در یادگیری مفاهیم و اطلاعات جدید در این حوزه.