
آموزش اصول سالید SOLID در برنامه نویسی شی گرا
آموزش اصول سالید SOLID در برنامه نویسی شی گرا یکی دیگر از آموزش های گروه آموزشی پرووید می باشد که در این قسمت آن را به شما معرفی می کنیم. این بسته ی آموزشی نیز یکی از دوره های آموزشی دیگر که در حوزه ی فارسی سازی آموزش های انگلیسی تنظیم شده است می باشد. عنوان این بسته ی آموزشی آموزش اصول SOLID در طراحی شی گرا است که با نام اصلی SOLID Principles of Object Oriented Design از شرکت Pluralsight منتشر شده است.
اصول طراحی شی گرا SOLID چیست؟
SOLID مخفف پنج اصل بسیار مهم در مدیریت وابستگی (Dependency Management) در توسعه ی برنامه های شی گرا می باشد. در واقع هر کدام از حروف کلمه ی SOLID به یکی از این اصول بر می گردد.
یکی از مشکلاتی که طراحی نامناسب برنامه های شی گرا برای برنامه نویسان ایجاد می کند موضوع مدیریت وابستگی در اجزای برنامه می باشد. اگر این وابستگی به درستی مدیریت نشود مشکلاتی شبیه موارد زیر در برنامه ایجاد می شوند:
- برنامه ی نوشته شده را نمی توان تغییر داد و یا قابلیت جدید اضافه کرد. دلیل آن هم این است که با ایجاد تغییر در قسمتی از برنامه، این تغییر به صورت آبشاری در بقیه ی قسمت ها منتشر می شود و مجبور خواهیم بود که قسمت های زیادی از برنامه را تغییر دهیم. (این مشکل را Rigidity می نامیم.)
- تغییر دادن برنامه مشکل است و آن هم به این دلیل که با ایجاد تغییر در یک قسمت از برنامه، قسمت های دیگر برنامه از کار می افتند و دچار مشکل می شوند. (این مشکل را Fragility می نامیم.)
- قابلیت استفاده مجدد از اجزای برنامه وجود ندارد. در واقع، قسمت های مجدد برنامه ی شی گرای شما آنچنان به هم وابستگی تو در تو دارند که به هیچ وجه نمی توانید یک قسمت را جدا کرده و در برنامه ی دیگری استفاده کنید. (این مشکل را Immobility می نامیم.)
اصول SOLID که قصد رفع کردن این مشکلات و بسیاری مسائل گوناگون را دارند عبارت اند از:
- Single Responsibility Principle
- Open-Closed Principle
- Liskov Substitution Principle
- Interface Segregation Principle
- Dependency Inversion Principle
با کنار هم گذاشتن حرف اول هر کدام از این اصول کلمه ی SOLID ایجاد می شود. با در نظر گرفتن این پنج اصل و پیاده سازی آنها در برنامه های خود می توانید به یک طراحی شی گرا پاک و درست دست پیدا کنید.
اصول سالید و یا SOLID Principle در واقع ۵ اصل هستند که در طراحی شی گرا برنامه نویسی مورد استفاده قرار می گیرد. به بیان دیگر، این اصول مجموعه قوانین و best practice هایی هستند که می توانید در طراحی کردن یک برنامه شی گرا از آنها استفاده کنید. استفاده کردن از این ۵ اصل کمک می کنند تا شما بتوانید design pattern های مورد نیاز در برنامه خود را کشف کرده و معماری مناسب تری را در برنامه پیاده سازی کنید. یادگیری اصول سالید و استفاده کردن از آنها یکی از مهمترین توانمندی هایی است که یک برنامه نویس باید بتواند آنها را کسب کند. ضمناً کلمه سالید سرنام 5 اصل بسیار مهم است که در ادامه آن ها را به صورت تیتروار خدمتتان عرض می کنیم:
- The Single Responsibility PrincipleThe Open-Closed Principle
- The Liskov Substitution Principle
- The Interface Segregation Principle
- The Dependency Inversion Principle
در ادامه سعی می کنیم که کمی در رابطه با هر کدام از این اصول صحبت کنیم.

اصل Single Responsibility Principle: اصل تک وظیفه ای بودن و یا single responsibility principle بیان می کند که یک کلاس فقط باید یک تک وظیفه را داشته باشد و به همین دلیل فقط یک دلیل برای تغییر کردن داشته باشد. اگر بخواهیم این اصل را به صورت فنی تر بیان کنیم می توانیم بگوییم که فقط یک تغییر بالقوه یعنی تغییر در database logic و یا logging logic و الی آخر در یک نرم افزار بایستی که بر روی تعریف یک کلاس تغییر ایجاد کند.
اصل Open-Closed Principle: تغییر به معنی ایجاد تغییر بر روی کد هایی که از قبل نوشته اید می باشد و گسترش به معنی اضافه کردن قابلیت های جدید است. براساس اصل open-closed principle یک نرم افزار بایستی برای ایجاد تغییر، بسته و برای گسترش، باز باشد.
اصل Liskov Substitution Principle: اصل liskov substitution principle بیان می کند که یک subclass باید بتواند جایگزین base class های خود شود.
اصل Interface Segregation Principle: تفکیک یا segregation به معنی جدا کردن اجزای مختلف از یکدیگر است و بنابراین interface segregation principle به معنی تفکیک کردن اینترفیس ها می باشد. براساس این اصل داشتن اینترفیس های کوچکتر و خاص تر بهتر از داشتن اینترفیس های حجیم و عمومی است. کلاینت ها و یا مصرف کننده های یک اینترفیس نباید مجبور باشند که توابعی که از قبل از آنها استفاده نمی کنند را صرف اینکه در یک اینترفیس وجود دارند، پیاده سازی کنند.
اصل Dependency Inversion Principle: اصل dependency inversion principle و یا معکوس سازی وابستگی به این معنی است که کلاس های ما باید به اینترفیس ها و یا abstract class ها وابسته باشند و وابستگی مستقیم به توابع و یا concrete class ها نداشته باشند.
اصل Single Responsibility در طراحی کلاس های C# چیست؟
اصل Single Responsibility بیان میکند که هر کلاس بهتر است مسئولیت مشخص و متمرکزی داشته باشد و در برابر یک نوع دلیل برای تغییر قرار بگیرد. اگر یک کلاس همزمان منطق کسبوکار، ذخیرهسازی داده و تولید گزارش را مدیریت کند، تغییر در هر یک از این بخشها میتواند آن را تحت تأثیر قرار دهد. تفکیک مسئولیتها باعث میشود هدف هر کلاس روشنتر باشد و توسعهدهنده بتواند بدون درگیر شدن با وظایف نامرتبط، تغییرات مورد نیاز را اعمال کند.
رعایت این اصل به معنای ساختن تعداد زیادی کلاس کوچک بدون دلیل نیست. هدف، ایجاد مرزهای معنادار میان وظایف مختلف است تا هر بخش از نرمافزار بتواند با پیچیدگی کمتری توسعه پیدا کند. برای مثال، میتوان منطق محاسبه هزینه سفارش را از مسئولیت ذخیرهسازی آن جدا کرد. در چنین ساختاری، تغییر روش ذخیرهسازی لزوماً به تغییر منطق محاسباتی منجر نمیشود. این تفکیک همچنین خوانایی کد و امکان تست کردن رفتار هر بخش را بهبود میدهد.
اصل Open/Closed چگونه به توسعه پذیر بودن نرم افزار کمک می کند؟
اصل Open/Closed بر این ایده تأکید دارد که اجزای نرمافزار باید برای توسعه رفتار باز باشند، اما برای تغییرات مکرر در کد موجود تا حد امکان بسته بمانند. منظور این نیست که کد هرگز نباید تغییر کند، بلکه بهتر است افزودن قابلیتهای جدید در شرایط مناسب از طریق گسترش ساختار موجود انجام شود. استفاده از abstractionها و تعریف قراردادهای روشن میتواند به پیادهسازی این اصل کمک کند و نیاز به تغییر مداوم بخشهای پایدار برنامه را کاهش دهد.
برای مثال، اگر یک سیستم محاسبه هزینه برای چند نوع سفارش طراحی شده باشد، افزودن نوع جدید نباید الزاماً به بازنویسی تمام منطق محاسبه منجر شود. میتوان با تعریف یک interface مشترک و پیادهسازی رفتارهای متفاوت، امکان گسترش سیستم را فراهم کرد. البته این روش باید متناسب با نیاز واقعی انتخاب شود؛ ایجاد abstraction برای هر احتمال فرضی میتواند طراحی را بیجهت پیچیده کند. اصل Open/Closed زمانی مفید است که نقاط محتمل تغییر شناسایی و با ساختاری مناسب مدیریت شوند.
اصل Liskov Substitution و Interface Segregation چه کاربردی دارند؟
اصل Liskov Substitution بیان میکند که نمونههای یک نوع پایه باید بتوانند بدون برهم زدن رفتار مورد انتظار برنامه، با نمونههای انواع مشتقشده جایگزین شوند. اگر یک کلاس فرزند محدودیتهایی ناسازگار با قرارداد کلاس پایه ایجاد کند، استفاده از آن میتواند به خطاهای غیرمنتظره منجر شود. رعایت این اصل مستلزم آن است که رفتار انواع مشتقشده با انتظارات تعریفشده برای نوع پایه سازگار بماند و وراثت فقط بر اساس شباهت ظاهری کلاسها انتخاب نشود.
اصل Interface Segregation نیز توصیه میکند بهجای interfaceهای بزرگ با متدهای نامرتبط، قراردادهای کوچکتر و متناسب با نیاز مصرفکنندگان تعریف شوند. برای مثال، اگر یک کلاس فقط به قابلیت خواندن اطلاعات نیاز دارد، نباید مجبور باشد وابستگی به متدهای تغییر یا حذف داده را نیز بپذیرد. این رویکرد وابستگیهای غیرضروری را کاهش میدهد و تغییر قراردادها را سادهتر میکند. ترکیب این دو اصل به طراحی انواع و interfaceهایی کمک میکند که رفتار قابل پیشبینیتری دارند و استفاده از آنها در بخشهای مختلف برنامه آسانتر است.
اصل Dependency Inversion و DRY در برنامه نویسی شی گرا
اصل Dependency Inversion توصیه میکند ماژولهای سطح بالا و پایین بهجای وابستگی مستقیم به یکدیگر، بر اساس abstractionهای مناسب ارتباط برقرار کنند. با این روش، منطق اصلی برنامه کمتر به جزئیات یک پیادهسازی مشخص وابسته میشود و جایگزین کردن فناوریها یا اجزای اجرایی آسانتر خواهد بود. برای نمونه، منطق کسبوکار میتواند به یک interface برای ذخیرهسازی وابسته باشد، بدون اینکه مستقیماً با کلاس مخصوص یک پایگاه داده در ارتباط باشد. این اصل در کنار سایر اصول SOLID به ایجاد ساختار منعطفتر کمک میکند.
اصل Don't Repeat Yourself یا DRY نیز بر کاهش تکرار غیرضروری دانش و منطق در سیستم تأکید دارد. اگر یک قانون کسبوکار در چند بخش مستقل از کد تکرار شود، تغییر آن ممکن است نیازمند اصلاح چند نقطه باشد و احتمال ناسازگاری افزایش پیدا کند. با این حال، هر تکرار ظاهری الزاماً به معنای وجود منطق مشترک نیست؛ ادغام کدهایی که دلایل تغییر متفاوتی دارند نیز میتواند وابستگی نامناسب ایجاد کند. هدف DRY جلوگیری از تکرار دانش یکسان و حفظ هماهنگی رفتار سیستم در طول توسعه است.
سرفصل مطالب آموزش ویدئویی اصول SOLID در طراحی شی گرا
فصل اول: اصل Single Responsibility
- مقدمه
- تعریف اصل Single Responsibility
- Responsibility ها چه هستند؟
- بررسی عملی مشکلی که نقض اصل Single Responsibility به وجود می آورد
- تجزیه و تحلیل مشکل
- ریفکتور کردن برای رسیدن به طراحی بهتر
- جمع بندی
- مقدمه
- تعریف اصل Open/Closed
- بررسی عملی مشکلی که نقض اصل Open/Closed به وجود می آورد
- تجزیه و تحلیل مشکل
- ریفکتور کردن برای رسیدن به طراحی بهتر
- مقدمه
- تعریف اصل Liskov Substitution
- بررسی عملی مشکلی که نقض اصل Liskov Substitution به وجود می آورد
- تجزیه و تحلیل مشکل
- Design Smell های مربوط به اصل Liskov Substitution
- ریفکتور کردن برای رسیدن به طراحی بهتر
- نکات
- جمع بندی
- مقدمه
- بررسی عملی مشکلی که نقض اصل Interface Segregation به وجود می آورد
- تجزیه تحلیل مشکل
- ریفکتور کردن برای رسیدن به طراحی بهتر
- Design Smell ها و نکات مربوط به اصل Interface Segregation
- جمع بندی
- مقدمه
- تعریف اصل Dependency Inversion
- Dependency ها چه هستند؟
- برنامه نویسی سنتی و مشکل مربوط به معماری سه لایه ی سنتی
- Dependency های کلاس ها
- بررسی یک برنامه به صورت عملی
- بررسی عملی مشکلی که نقض اصل Dependency Inversion به وجود می آورد
- انجام ریفکتورینگ ها
- Design Smell ها
- مکان مناسب برای Instantiate کردن Dependency ها
- IoC Container ها
- جمع بندی
- مقدمه
- تعریف اصل Dependency Inversion
- Dependency ها چه هستند؟
- برنامه نویسی سنتی و مشکل مربوط به معماری سه لایه ی سنتی
- Dependency های کلاس ها
- مقدمه
- تعریف اصل Don't Repeat Yourself
- برنامه ی نمونه و تجزیه و تحلیل آن
- ریفکتور کردن Magic String ها
- ریفکتور کردن کدهای تکراری (Duplicate Logic)
- ریفکتور کردن دستورات if-then تکراری
- ریفکتور کردن دستورارت شرطی به Polymorphism
- جمع بندی
- مقدمه
- تجزیه و تحلیل
- تست ها و متدهای Static و مشکل Static Cling
- اضافه کردن Integration Test ها
- اضافه کردن Unit Test ها
- استفاده کردن از Mock Object ها
- جمع بندی
- مقدمه
- تجزیه و تحلیل
- تعریف و کشف Repeated Execution Pattern ها
- ریفکتور کردن با استفاده از دیلیگیت جنریک Action
- ریفکتور کردن Data Access با SQLHelper
- کشف کدهای تکراری با ابزار Atomiq
- فرآیند تولید کد (Code Generation)
- فرآیندهای تکراری توسعه ی نرم افزار (Test-Build-Deploy)
- Automation و ابزار MSBuild برای رفع فرآیندهای ترکاری
- جمع بندی







