اصول solid در سی شارپ
اصول solid در سی شارپ
در این مقاله از سری مقالات آموزشی در آکادمی استادباش به بررسی اصول solid در سی شارپ میپردازم. اصول solid در سی شارپ جزو اصول طراحی پایه هستن. کلمه solid برگرفته از پنج سرواژه حروف:
- S:Single Responsibility Principle - SRP
- O:Open Closed Principle - OCP
- L:Liskov Substitution Principle - LSP
- I:Interface Segregation Principle - ISP
- D:Dependency Inversion Principle - DIP
هست که به ترتیب هرکدوم برای حل بخشی از مشکلات در برنامه نویسی شی گرایی استفاده میشه. البته منظور از مشکلات اینه که در نهایت با رعایت نکردنشون بعد از مدتی و همچنین توسعه پروژه، با حجم زیادی از کد های ناکارآمد و غیر قابل نگهداری روبرو هستیم که توصیه میشه از ابتدای هر پروژه این اصول رو در اولویت توسعه خودتون قرار بدین.
دلیل پشت پرده ناموفق بودن اکثر برنامه ها
توسعه دهنده ها در ابتدا با استفاده ازطراحی های خوب و مرتبشان بر اساس دانشی که دارن، شروع به ایجاد برنامه ها می کنن. اما با گذشت زمان تو برنامه ها خطاها و مشکلاتی بوجود میاد. طراحی برنامه ما باید برای هر درخواست جدید و یا تغییراتی در بخش مورد نظر، تغییر کنه که در نتیجه بعد از مدتی باید زحمات و تغییرات زیادی رو انجام بدیم حتی برای کوچک ترین کارها. اما خب قطعا نمیتونیم بهونه تراشی کنیم و یا این تغییرات جدید رو سرزنش کنیم که آی ی ی چر از اول نگفتین یا الان دیگه نمیشه.اونا بخشی از توسعه نرم افزار ما هستن. ما نمیتونیم جلوی اونارو بگیریم.خب مقصر کیه اینجا ؟ قطعا جواب، طراحیه نرم افزار ماست. مواردی رو که در زیر بهش اشاره کردم، بیشترین آسیب ها رو در طراحی نرم افزار ها به وجود میاره.
- اضافه کردن فشار بیشتر بر روی کلاس ها با افزایش مسئولیت های بیشتر (افزودن مسئولیت هایی که مربوط به کلاس نیست ).
- کلاس ها رو مجبور به وابسته بودن به همدیگه کنیم. اگه کلاس ها به همدیگه وابسته باشن که در اصطلاح میگیم Tightly Coupled، با تغییر تو یک کلاس، بقیه کلاس های وابسته هم تحت تاثیر قرار میگیرن.
- داپلیکیت کد ها یا همون نوشتن کد های تکراری.
راه حل
- انتخاب یک معماری صحیح بر حسب نیاز.
- پیروی کردن از اصول طراحی.
- انتخاب یک Design Pattern مناسب برای ساخت نرم افزار ها بر اساس مشخصاتشون.
آشنایی با اصول solid در سی شارپ
solid principle ها یا همون اصول solid، یک سری اصول طراحی هستن که مارو قادر میسازن خیلی از مشکلات طراحی نرم افزار ها رو مدیریت کنیم. رابرت مارتین که همه ما اون رو به آنکل باب هم میشناسیم این اصول رو در سال 1990 تدوین کرد. این اصول به ما کمک میکنه تا کد های Tightly Coupled (این مغهوم زمانی به کار برده میشه که وابستگی بین کلاس ها زیاد باشه و در نتیجه با تغییر در یک کلاس، کلاس های زیاد دیگه ای تحت تاثیر قرار بگیره) و همچنین کد هایی که از کپسوله پایینی برخوردارن رو ارتقا بدیم و ببریم به سمت کد هایی که در نهایت loosely coupled (حذف و به حداقل رساندن وابستگی بین کلاس ها سبب ایجاد کلاس هایی میشه که بهش میگیم loosely coupled) هستن و همچنین از کپسوله سازی بالایی برخوردارن.
آشنایی با مفهوم PDD یا Pain Driven Development
اولین سوالی که ممکنه براتون پیش بیاد اینه که این اصول رو چه زمانی میشه در طراحی نرم افزار استفاده کرد ؟ جواب سادست. هر زمان که یاد گرفتیم و تسلط پیدا کردیم باید همیشه و در همه قسمت های نرم افزار از این اصول پیروی کنیم. اما قبل از اینکه بخوام شروع کنم و در مورد اصول سالید توضیح بدم بیاین با یک مفهوم آشنا بشیم. قطعا با مفاهیمی مثل TDD و یا DDD آشنا هستین.مفهوم دیگه ای که میخوام در موردش توضیح بدم،PDD هست که برگرفته از Pain Driven Development. این مفهوم به ما میگه با دانشی که دارین، کدتون رو در ساده ترین حالت ممکن برای حل مسائل بنویسین و نگران solid هم نباشین و لزومی نداره که در ابتدا همه این اصول رو پیاده سازی کنین. پیاده سازی این اصول در ابتدای کار باعث بهینه سازی زودهنگام میشه و شعار این روش هم در اینه که از بهینه سازی زودهنگام یا Premature Optimization خودداری کنیم. در عوض در هنگام توسعه پروژه بررسی کنیم ببینیم کجای پروژه مشکل داره. مشکلات میتونن خودشون رو در قالب تست پذیری سخت، کد های تکراری و یا وابستگی های زیاد نشون بدن.وقتی هر کدوم از این مشکلات رو دیدین، سعی کنین با یکی از اصول solid که قابل حله اون مشکل رو برطرف کنین.
اصل Single Responsibility Principle یا SRP در سی شارپ
هر کدوم از این اصول در برگیرنده یک مفهومه که برای حل مشکلی در کدنویسی ارائه شده. مثلا اصل اول یا Single Responsibility Principle در مورد مسئولیت واحد صحبت میکنه و میگه هر کلاس، فانکشن یا متدی که در برنامه ایجاد میکنین، فقط برای یک کار ایجاد بشه و توسعه دهنده فقط یک دلیل برای تغییر اون داشته باشه. مثلا ما اومدیم یه کلاس به نام پروفایل کاربر ساختیم که اخلش یه سری متد داریم، مثلا دریافت کاربر بر اساس کد ملی، افزودن پروفایل کابر، ویرایش پروفایل و در آخر اعتبار سنجی پروفایل کاربر. با قراردادن متد اعتبار سنجی پروفایل کاربر اصل SRP رو نقض کردیم. شاید با خودتون بگین چرا ؟ جواب سادت. اعتبار سنجی باید در یک کلاس جداگونه صورت بگیره و ربطی به کلاس پروفایل کاربر نداره. پس باید یه کلاس جدا داشته باشیم برای اعتبار سنجی هامون و در اون کلاس بر اساس پالیسی های مد نظرمون اعتبار سنجی رو انجام بدیم. برای اینکه بیشتر با این مفهوم آشنا بشین مقاله اصل Single Responsibility در سی شارپ رو بخونین. کامل توضیح دادم.
اصل Open Closed Principle یا OCP در سی شارپ
اصل دوم یا Open Closed Principle میگه کدی که مینویسین برای توسعه باز باشه اما برای تغییر نه. این مفهوم شاید در ابتدا یه کمی گنگ باشه اما بسیار سادس. فرض رو بر این بذارین که در برنامتون برای محاسبه هزینه ارسال به دو روش زمینی و هوایی یک کلاس ایجاد کردین و با یک کاندیشن بررسی میکنین که اگر روش زمینی بود فلان قیمت، اگه روش هوایی بود فلان قیمت دیگه. تا اینجا مشکلی نیست. حالا فرض کنین که در آینده یک روش حمل دیگه هم به سیستم اضافه میشه مثلا دریایی و شما باید برای محاسبه هزینه این روش یک کاندیشن مجدد به این کلاس اضافه کنین و بگین اگه روش دریایی بود فلان قیمت. خب اینجا ما اصل Open Closed Principle رو نقض کردیم و اما اینکه چه روشی مناسب هست و میتونیم برای رعایت این اصل استفاده کنیم در مقاله اصل Open Closed Principle در سی شارپ اون رو بررسی می کنیم.
اصل Liskov Substitution Principle یا LSP در سی شارپ
اصل سوم یا Liskov Substitution Principle در مورد این صحبت می کنه که اگه از Inheritance استفاده می کنیم، مطمئن باشیم که کلاس ها کاملا به جای همدیگه میتونن استفاده بشن. مثلا فرض کنین یه کلاس داریم به اسم مدیریت فایل که دو تا متد داره، یکی برای خوندن از فایل و اون یکی برای نوشتن در فایل. حالا دو تا کلاس یوزر و ادمین هم داریم که از کلاس مدیریت فایل ارث بری میکنن. کلاس ادمین میتونه هم یک فایل رو ایجاد کنه و هم یک فایل رو بخونه، پس میتونه هر دو تا متد رو به درستی پیاده سازی کنه و ازشون استفاده کنه، در صورتی که کلاس یوزر فقط میتونه یک فابل رو بخونه و در صورتی که بخواد یک فایل رو بنویسه یا ایجاد کنه، اکسپشن تولید میشه. اینجا اصل LSP داره نقض میشه. میدونم شادی براتون این مفهوم یک کم گیج کننده باشه. این رو هم در قالب یک مثال عملی در مقاله Liskov Substitution Principle در سی شارپ بررسی کردم.
اصل Interface Segregation Principle یا ISP در سی شارپ
اصل چهارم یا Interface Segregation Principle میگه تا میتنونین اننتزاع ها رو جدا کنین. کلاینت (منظور کدی که با نمونه های ساخته شده ی شما سرو کار داره) نباید متدی رو که لازم نداره پیاده سازی کنه. فرض کنین تو یه شرکت یه سری کارمند داریم که بر اساس نوع کارشون، میزان حقوقشون محاسبه میشه. مثلا یه عده هستن که بر اساس ورود و خروجشون محاسبه میشه و یه عده دیگه بر اساس گزارش روزانه ای که تحویل میدن. حالا اگه ما یه اینترفیس کلی برای محاسبه حقوق کارمندای شرکت داشته باشیم میتونه شامل سه تا متد باشه : یکی برای ثبت ورود کارمندا، یکی برای ثبت خروجشون و اون یکی هم برای دریافت گزارش روزانه تا بتونه حقوق رو بر اساس این متد ها محاسبه کنه. حالا کلاس کارمند ما که این اینترفیس رو پیاده سازی کنه دو حالت داره، یا جزو ورود و خروجی هاست که به متد گزارش روزانه نیازی نداره و یا جزو گزارشی هاس که به دو تا متد ورود و خروج نیازی نداره. این حالت اصل ISP رو نقض میکنه و راح حل اینه که دو تا اینترفیس داشته باشیم یکی برای محاسبه گزارشی ها و اون یکی هم برای محاسبه ورود و خروجی ها. این طوری هم انسجام یا Cohesion اینترفیس ها بیشتر میشه، هم SRP رو رعایت کردیم و هم اصل ISP رو به بهترین حالت ممکن پیاده سازی کردیم. در این مورد یه مثال کامل به همراه نمونه کد در مقاله Interface Segregation Principle در سی شارپ آماده کردم.
اصل Dependency Inversion Principle یا DIP در سی شارپ
اصل پنجم و آخرین اصل از مجموعه اصول solid یا Dependency Inversion Principle در مورد معکوس سازی وابستگی ها صحبت میکنه و میگه کلاس های سطح بالا نباید به کلاس های سطح پایین تر خودشون وابسته باشن. بلکه هر دوی اونا باید به انتزاع ها وابسته باشن و همینطور میگه که انتزاع ها هم نباید به جزییات وابسته باشن بلکه این جزییات هستن که باید به انتزاع ها وابسته باشن. این مورد رو پیشنهاد می کنم در مقاله اصل Dependency Inversion Principle در سی شارپ مطالعه کنین. به صورت کامل به همراه نمونه کد براتون توضیح دادم.
حالا با مفهوم solid آشنا شدیم و در مقاله های بعدی با هر کدوم از این اصول پنج گانه بیشتر آشنا میشیم و مثال هایی رو باهم بررسی می کنیم.