در این پست از وبسایت پرووید در رابطه با بررسی اصل Single Responsibility Principle در برنامه نویسی شی گرا صحبت خواهیم کرد.

بررسی اصل Single Responsibility Principle

اصل اول از سری اصول پنجگانه SOLID در طراحی و کدنویسی شی‌گرا اصل Single Responsibility Principle می‌باشد، که به طور کوتاه به آن SRP نیز می‌گویند. براساس این اصل هیچگاه نباید بیش از یک دلیل برای تغییر در طراحی یک کلاس وجود داشته باشد. به عبارت دیگر هر کلاس یا هر Struct فقط باید یک وظیفه تک را انجام بدهد و تمامی اعضای عضو یک کلاس یا Struct که به آن‌ها Member نیز می‌گوئیم، باید بروی آن تک وظیفه متمرکز شده و فقط هدف آن‌ها انجام آن رسالت باشد.

بسته ی آموزش ویدئویی ریفکتورینگ در سی شارپ

از شما دعوت می کنیم که از بسته ی آموزش ویدئویی ریفکتورینگ در سی شارپ دیدن کنید.

دقت کنید که اصل SRP به این معنی نیست که کلاس‌های شما فقط باید حاوی یک Method یا یک Property باشند. یک کلاس می‌تواند تعداد بیشماری Property یا Method داشته باشد. اما تا زمانی که تمامی آن‌ها بروی انجام تک وظیفه‌ای که آن کلاس دارد متمرکز شده باشند، از نظر اصل SRP هیچ مشکلی وجود ندارد.

استفاده از اصل SRP می‌تواند، کد شی‌گرا را به طور چشمگیری تغییر بدهد. یکی از این تغییرات کلیدی این است که در پروژه‌‌های شما کلاس‌ها، ساده‌تر، تمیزتر و کوچکتر خواهند بود. در رابطه با نوشتن کدهای تمیز از بسته ی آموزش ویدئویی کدنویسی تمیز: نوشتن کد برای انسان ها استفاده کنید. تعداد کلاس‌های درون یک پروژه ممکن است، افزایش پیدا کنند، اما این کلاس‌ها کوچکتر و تمیزتر خواهند بود. دقت کنید که با افزایش تعداد کلاس‌ها، اهمیت سازماندهی آن‌ها با استفاده از Namespace ها و Folder ها افزایش می‌یابد.

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

بسته ی آموزش ویدئویی شی گرایی پیشرفته در سی شارپ

از شما دعوت می کنیم که از بسته ی آموزش ویدئویی شی گرایی پیشرفته در سی شارپ دیدن کنید.

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

مثال کاربردی

به منظور درک هر چه بهتر اصل Single Responsibility Principe یک مثال از کدهای سی شارپ که این اصل را زیر پا گذاشته است را بررسی کرده و سپس اقدام به Refactor کردن آن خواهیم کرد. به منظور یادگیری مباحث Refactoring می‌توانید، از بسته آموزش Refactoring در سی شارپ استفاده کنید. لطفا به کد زیر که تعریف یک کلاس را نشان می‌دهد، دقت کنید.

public class OxygenMeter
{
    public double OxygenSaturation { get; set; }
 
    public void ReadOxygenLevel()
    {
        using (MeterStream ms = new MeterStream("O2"))
        {
            int raw = ms.ReadByte();
            OxygenSaturation = (double)raw / 255 * 100;
        }
    }
 
    public bool OxygenLow()
    {
        return OxygenSaturation <= 75;
    }
 
    public void ShowLowOxygenAlert()
    {
        Console.WriteLine("Oxygen low ({0:F1}%)", OxygenSaturation);
    }
}

همانطور که در کد بالا مشاهده می‌کنید، کلاسی به نام OxygenMeter تعریف کرده‌ایم. وظیفه این کلاس اندازه‌گیری سطح اکسیژن در آب می‌باشد که با یک دستگاه سخت‌افزاری کار می‌کند. این کلاس دارای یک Method به نام OxygenLevel می‌باشد، که یک Value را از یک جویباری از آب دریافت کرده و سپس این Value را به درصد تبدیل کرده و در OxygenSaturation ذخیره می‌کند. متد دوم OxygenLow نام دارد. وظیفه این Method کنترل کردن OxygenSaturation می‌باشد که اطمینان حاصل کند که این مقدار، از حداقل 75 درصد بیشتر است. متد آخر که ShowLowOxygenLers نام دارد، به منظور نشان دادن یک اخطار در رابطه با پائین بود سطح Saturation آب تعریف شده است.

بسته ی آموزش ویدئویی اصول SOLID در طراحی شی گرا

از شما دعوت می کنیم که از بسته ی آموزش ویدئویی اصول SOLID در طراحی شی گرا دیدن کنید.

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

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

ریفکتور کردن کد

به منظور ریفکتور کردن کلاسی که تعریف کرده ایم، آن را به چندین کلاس مختلف خواهیم شکست. نام کلاس اول را OxygenMeter می‌گذاریم. در این کلاس پروپرتی OxygenSaturation و همچنین متد ReadOxygenLevel را نگه خواهیم داشت. ممکن است حتی به این فکر کنیم که این دو Member را نیز در دو کلاس جداگانه قرار بدهیم ولی در این مثال به همین موضوع بسنده میکنیم چرا که این Property و Method شدیداً به یکدیگر مرتبط هستند.

public class OxygenMeter
{
    public double OxygenSaturation { get; set; }
 
    public void ReadOxygenLevel()
    {
        using (MeterStream ms = new MeterStream("O2"))
        {
            int raw = ms.ReadByte();
            OxygenSaturation = (double)raw / 255 * 100;
        }
    }
}

دیگر متدها را نیز در دو کلاس جداگانه قرار می‌دهیم، تا برای کلاس OxygenMeter فقط یک دلیل برای تغییر کردن وجود داشته باشد و آن یک دلیل هم تغییر کردن سخت افزاری است که این کلاس از آن استفاده می کند تا سطح Saturation یا غلظت آب را بررسی کند.

کلاس دومی که ایجاد کردیم را OxygenSaturationChecker نامگذاری کرده‌ایم. این کلاس دارای یک Method تک می باشد که سطح اکسیژن آب را با حداقل میزان قابل پذیرش مقایسه می کند. دقت کنید که متدی که در این کلاس قرار داده ایم، همان متدی است که در کلاس اول قرار داشت با این تفاوت که یک پارامتر از نوع کلاس OxygenMeter به درون این کلاس تزریق شده است. در رابطه با Dependency Injection از بسته ی آموزش ویدئویی Inversion of Control و IoC Container ها و آموزش ویدئویی Dependency Injection در برنامه نویسی شی گرا در وب سایت پرووید استفاده کنید.

public class OxygenSaturationChecker
{
    public bool OxygenLow(OxygenMeter meter)
    {
        return meter.OxygenSaturation &lt;= 75;
    }
}

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

بسته ی آموزش ویدئویی Inversion of Control و IoC Container ها

از شما دعوت می کنیم که از بسته ی آموزش ویدئویی Inversion of Control و IoC Container ها دیدن کنید.

کلاس آخر کلاس OxygenAlerter می باشد که وظیفه نشان دادن یک اخطار را دارد.  شبیه به کلاس قبل نیز یک Dependency از نوع OxygenMeter به درون این کلاس تزریق شده است. برای کلاس OxygenAlerter فقط یک دلیل برای تغییر کردن وجود دارد و آن هم تغییر در سیستم نشان دادن اخطار است.

public class OxygenAlerter
{
    public void ShowLowOxygenAlert(OxygenMeter meter)
    {
        Console.WriteLine("Oxygen low ({0:F1}%)", meter.OxygenSaturation);
    }
}

کدی که در قسمت زیر مشاهده میکنید نسخه ریفکتور شده کلاس OxygenMeter می باشد.

public class OxygenMeter
{
    public double OxygenSaturation { get; set; }
 
    public void ReadOxygenLevel()
    {
        using (MeterStream ms = new MeterStream("O2"))
        {
            int raw = ms.ReadByte();
            OxygenSaturation = (double)raw / 255 * 100;
        }
    }
}
 
     
public class OxygenSaturationChecker
{
    public bool OxygenLow(OxygenMeter meter)
    {
        return meter.OxygenSaturation &amp;amp;lt;= 75;
    }
}
     
 
public class OxygenAlerter
{
    public void ShowLowOxygenAlert(OxygenMeter meter)
    {
        Console.WriteLine("Oxygen low ({0:F1}%)", meter.OxygenSaturation);
    }
}

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

امیدواریم که این آموزش از وبسایت پرووید نیز مورد توجه تمامی دوستان عزیز قرار گرفته باشد. لیست کامل این آموزش را می توانید در پست مربوط به آموزش اصول SOLID در برنامه نویسی شی گرا مشاهده کنید.

پاسخی بگذارید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *