برنامه نویسی شی گرا به ما قدرت خیلی زیاده داده و با استفاده از آنها کارهایی را می توانیم انجام دهیم که قبل از آن امکان را نداشتیم.
اما این شی گرایی معایبی هم برای ما دارد برای مثال در بعضی مواقع باعث بیش از حد پیچیدگی کدهای ما می شود.
در آموزش برنامه نویسی اصلی داریم که به SOLID معروف است و با رعایت این اصول میتوانیم برنامه ای تمیز تر طراحی کنیم.
بخش های الگوی SOLID
SOLID مخفف عبارت زیر است:
- S: Single Responsibility Principle
- O: Open-Closed Principle
- L: Liskov Substitution Principle
- I: Interface Segregation Principle
- D: Dependency Inversion Principle
Single Responsibility Principle
Single Responsibility Principle (SRP) در اصل SOLID یکی از اصول مهم برنامهنویسی شیءگرا است.
این اصل میگوید که هر کلاس یا ماژول در یک برنامه باید فقط یک مسئولیت وظیفهای داشته باشد و به عبارت دیگر، هر ماژول باید تنها به یک دلیل برای تغییر پذیری تغییر کند.
این اصل به معنای تقسیم بندی مسئولیتها و وظایف برنامه به قسمتهای جداگانه است.
به جای داشتن یک کلاس یا ماژول کلی که همه وظایف را انجام میدهد، باید آن را به بخشهای کوچکتر و قابل مدیریتتری تقسیم کنید.
مزایای اصل SRP عبارتند از:
- کد خوانا و قابل فهمتر: با تقسیم کد به قسمتهای کوچکتر و مجزا، کد به شکلی منظم و خوانا تر خواهد بود و سایر برنامهنویسان بتوانند به راحتی آن را فهمیده و تغییر دهند.
- قابلیت تستپذیری: هر قسمت کد مستقل میشود و میتوانید آن را به طور جداگانه تست کنید. این امر موجب میشود که تست و اشکالزدایی برنامه آسانتر و کارآمدتر باشد.
- افزایش قابلیت توسعه: با تقسیم مسئولیتها به قسمتهای کوچکتر، افزودن و تغییر وظایف به برنامه سادهتر میشود و برای اضافه کردن ویژگیهای جدید نیاز به تغییر کدهای قبلی کمتر میشود.
برای اجرای اصل SRP، میتوانید این راهنماییها را دنبال کنید:
- هر کلاس یا ماژول باید فقط برای انجام یک کار خاص طراحی شود.
- جدا کردن کدها بر اساس وظایف و منظورهای مشخصی که دارند.
- رعایت نکردن تلاقی مسئولیتها، به این معنی که هر ماژول فقط مسئولیت خاص خود را داشته باشد و درگیر مسائل مربوط به دیگر مسئولیتها نشود.
- وقتی نیاز به تغییر در یک ماژول پیش میآید، فقط باید به دلیل تغییر در مسئولیت آن باشد و تغییرات در سایر بخشها را ممنوع کنید.
به طور خلاصه، SRP به ما میگوید که هر قطعه کد باید فقط یک کار خاص را انجام دهد و بهتر است مسئولیتهای مختلف را به بخشهای جداگانه تقسیم کنیم تا کدمان قابل فهمتر، تستپذیرتر و توسعهپذیرتر باشد.
Open-Closed Principle
Open-Closed Principle (OCP) یکی دیگر از اصول SOLID در برنامهنویسی شیءگرا است.
این اصل بیان میکند که یک کلاس باید باز برای توسعه (Open) باشد، اما بسته برای تغییر (Closed).
به عبارت دیگر، هنگامی که نیازمندیها تغییر میکنند و ویژگیهای جدیدی به برنامه اضافه میشود، نباید کدهای قبلی را تغییر دهیم. بلکه باید از طریق توسعه کلاسها و ماژولها، بدون تغییر در کدهای موجود، قابلیت افزودن و تغییر ویژگیهای جدید را فراهم کنیم.
مزایای اصل OCP شامل موارد زیر است:
- کاهش احتمال ایجاد خطا: با عدم تغییر در کدهای موجود و فقط الحاق کردن ویژگیهای جدید، احتمال ورود خطا به بخشهای قبلی کاهش مییابد.
- توسعهپذیری و قابلیت استفاده مجدد بالا: با رعایت اصل OCP، کدهای توسعهپذیر و قابل استفاده مجدد طراحی میشوند. این امر به شما اجازه میدهد که ویژگیهای جدید را با استفاده از کد قبلی و تغییر کدهای موجود اضافه کنید.
- کاهش تداخلها: با تقسیم کد به بخشهای مجزا و اعمال تغییرات در بخشهای خاص، تداخلهای میان کدها کاهش مییابد و کد قابلیت خوانایی و نگهداری بهتری را پیدا میکند.
با اعمال اصل OCP، قادر خواهید بود به راحتی ویژگیهای جدید را به برنامه اضافه کرده و کد قبلی را تغییر داده و تغییرات را در کل برنامه اعمال نکنید. این امر توسعهپذیری و نگهداری کد را آسانتر میکند و ریسک بروز خطاها را کاهش میدهد.
Liskov Substitution Principle
اصل Liskov Substitution Principle (LSP) نیز یکی از اصول مهم SOLID در برنامهنویسی شیءگرا است. این اصل به معنای این است که اگر یک کلاس A زیرکلاسی از کلاس B است، باید بتوانیم نمونههای کلاس B را با نمونههای کلاس A جایگزین کنیم بدون اینکه صحت و جلوی درستی کارکرد برنامه را به خطر بیاندازیم.
به طور ساده، اگر برنامه شما بر روی یک کلاس B کار میکند، باید بتوانید به جای آن کلاس B را با هر کلاس A دیگری که از آن به عنوان یک زیرکلاس بهرهمندی میکند، قرار دهید، بدون اینکه عملکرد برنامه تغییر کند یا خطاها بوجود آیند.
برای رعایت اصل LSP، میتوانید این راهنماییها را دنبال کنید:
- رعایت قراردادهای واسط: زیرکلاسها باید قراردادهای واسط را که توسط کلاسهای بالاتر تعریف شدهاند، رعایت کنند. این به معنای تطابق متدها، ورودیها و خروجیها است.
- عدم افزایش پیششرطها: زیرکلاسها نباید پیششرطها را از کلاس بالاتر تشدید کنند. به عبارت دیگر، هر چیزی که در کلاس بالاتر مجاز است، در زیرکلاس نیز مجاز باید باشد.
- عدم کاهش پسشرطها: زیرکلاسها نباید پسشرطها را نسبت به کلاس بالاتر کاهش دهند. به عبارت دیگر، هر چیزی که در کلاس بالاتر انتظار میرود، در زیرکلاس نیز باید به همان شکل و درجه انتظار شود.
- عملکرد متدها در زیرکلاسها: متدهای زیرکلاسها باید به گونهای پیادهسازی شوند که نتیجهای که از متد کلاس بالاتر انتظار میرود، در زیرکلاس نیز به درستی بدست آید. با این کار، میتوانیم زیرکلاسها را بدون تغییر در برنامه جایگزین کنیم.
رعایت اصل LSP به ما کمک میکند که ساختار سلسلهمراتبی کلاسها را درست طراحی کنیم و بتوانیم کدها را با قابلیت استفاده مجدد بالا بسازیم. با رعایت این اصل، امکان تغییرات و توسعههای آینده را با کمترین تأثیر روی برنامه ایجاد میکنیم و از جانبی کیفیت و قابلیت نگهداری کد را بهبود میبخشیم.
Interface Segregation Principle
Interface Segregation Principle (ISP) در اصل SOLID، یکی از اصول مهم برنامهنویسی شیءگرا است. این اصل میگوید که باید واسطها را به گونهای طراحی کنیم که کلاسها فقط به آن قسمت از واسط نیاز داشته باشند که برای آنها لازم است. به عبارت دیگر، هیچ کلاسی نباید وابستگی به متدهایی داشته باشد که برایش معنایی ندارد.
مفهوم ISP در واقع به معنای تجزیه واسطها به قسمتهای کوچکتر و خصوصی است که تنها متدهای مرتبط با یک مفهوم و وظیفه خاص را شامل میشود. این اصل به ما میگوید که کلاسها باید تنها به آن قسمت از واسطها که نیاز دارند، وابسته باشند و بخشهای غیرضروری را نداشته باشند.
مزایای اصل ISP شامل موارد زیر است:
- جدا کردن مسئولیتها: با تجزیه واسطها به قسمتهای کوچکتر، مسئولیتهای مختلف به کلاسهای جداگانه تقسیم میشوند. این امر کمک میکند تا کدها معناشناختی راحتتری داشته باشند و هر کلاس فقط به وظایف خود متمرکز شود.
- کاهش وابستگیها: با تجزیه واسطها به بخشهای کوچکتر، وابستگیها به کدهای غیرضروری کاهش مییابد. این امر سبب میشود که تغییرات در یک بخش کوچکتر از واسط تأثیر کمتری روی کلاسهای دیگر داشته باشد.
- قابلیت توسعه و نگهداری بالا: با رعایت اصل ISP، کدها قابل توسعه و نگهداری بالا میشوند. اضافه کردن ویژگیهای جدید به کدها بدون تأثیر بر سایر بخشها امکانپذیر است.
برای رعایت اصل ISP، میتوانید این راهنماییها را دنبال کنید:
- طراحی واسطهای کوچکتر: واسطها را به قسمتهای کوچکتر تقسیم کنید که فقط مربوط به یک وظیفه خاص باشند.
- جدا کردن متدهای غیرضروری: از واسطها هر آن قسمتی که برای کلاسها معنایی ندارد، حذف کنید.
- ایجاد واسطهای خاص برای نیازهای خاص: به جای داشتن یک واسط کلی برای همه کلاسها، برای هر نیاز وظیفه خاص، یک واسط جداگانه ایجاد کنید.
اصل ISP به ما کمک میکند تا واسطها را به گونهای طراحی کنیم که کلاسها فقط به بخشهای مورد نیاز خود وابسته باشند. این امر از جانبی بهبود قابلیت خوانایی و نگهداری کد را دارد و کدهای قابل استفاده مجدد و توسعهپذیرتری را فراهم میکند.
Dependency Inversion Principle
Dependency Inversion Principle (DIP) نیز یکی از اصول مهم SOLID در برنامهنویسی شیءگرا است. این اصل به معنای وابستگی برعکس (inversion of dependency) است و به ما میگوید که کلاسها باید به واسطه توابع یا واسطهایی برای وابستگی خود به منابع خارجی وابسته شوند، نه به کلاسهای خارجی مستقیماً.
به عبارت دیگر، اصل DIP میگوید که باید به برنامهنویسی به شیوهای فکر کنیم که وابستگیها بر عکس از ترتیب معمول باشند. به جای اینکه کلاسها از جزئیات وابسته خودشان تعریف شوند، باید بر روی واسطها بنا شوند و از توابع و واسطهایی که مستقلاً ارائه میشوند استفاده کنند.
مزایای اصل DIP شامل موارد زیر است:
- کاهش وابستگیها: با استفاده از واسطها به جای کلاسهای خارجی، وابستگیها کاهش مییابند و کلاسها به کدی مستقل از جزئیات پیادهسازی وابسته میشوند.
- امکان تعویض منابع: با استفاده از واسطها و توابع مستقل، میتوانیم به راحتی منابع را تعویض کنیم بدون اینکه تغییراتی در کدها ایجاد شود. این امر از جانبی توسعهپذیری و قابلیت استفاده مجدد کد را بهبود میبخشد.
- تست و اشکالزدایی آسانتر: با استفاده از واسطها و توابع مستقل، تست کردن کد و اشکالزدایی آن سادهتر میشود. میتوانیم واسطها را مستقل از منابع وابسته به تست کنیم.
برای رعایت اصل DIP، میتوانید این راهنماییها را دنبال کنید:
- استفاده از واسطها: بجای وابستگی به کلاسهای خارجی، بر روی واسطها بنا کنید و از آنها استفاده کنید.
- جداسازی منطق اصلی: منطق اصلی برنامه را از جزئیات پیادهسازی جدا کنید و بر روی واسطها متمرکز شوید.
- استفاده از تزریق وابستگی: به جای ساخت وابستگیها درون کلاسها، از تزریق وابستگی (dependency injection) استفاده کنید تا منابع را به کلاسها تزریق کنید.
اصل DIP به ما کمک میکند تا کد را به گونهای طراحی کنیم که کلاسها به واسطه وابستگی خود به منابع خارجی، وابسته شوند، نه به کدهای خارجی مستقیماً. این امر امکان تعویض منابع، کاهش وابستگیها و تست و اشکالزدایی آسانتر را فراهم میکند و به کیفیت و قابلیت توسعه کد کمک میکند.