اصول S.O.L.I.D با تصاویر

اصول S.O.L.I.D با تصاویر

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

بنابراین هدف اصلی این مقاله درک بهتر این اصول با استفاده از تصاویر و برجسته کردن مهمترین هدف هر اصل است. همانطور که می بینید، بعضی از این اصول شبیه شی‌گرایی هستند اما هدف یکسانی را دنبال نمی‌کنند. برای درک ساده تر این موضوع، از لغت کلاس استفاده میکنم اما توجه داشته باشید که این لغت در این مقاله برای تابع، روش و ماژول هم استفاده می‌شود.

در این مقاله نظراتی درباره Open Closed  که اصل مسئولیت واحد را نقض میکند بیان شده است، لطفاً توجه داشته باشید که هدف این مقاله توضیح هر یک از این اصول  به طور مستقل است. در SRP از “I am Painter” و در Open-Closed از “I can Paint” استفاده شده است. به این نکته توجه داشته باشید زیرا اقدامات زیادی را میتوان برای انجام یک مسئولیت انجام داد. "کلاس باید یک مسئولیت داشته باشد" (SRP)، اما عملکرد آن که این مسئولیت را انجام می دهد باید برای "گسترش باز باشد" (OCP).

 

پنج اصل SOLID:

 S — Single Responsibility اصل مسئولیت واحد

Single responsibility principle

یک‌ کلاس باید یک مسئولیت واحد داشته باشد، اگر یک کلاس مسئولیت‌های متعددی داشته باشد احتمال به وجود آمدن خطا افزایش می یابد، زیرا اعمال تغییرات در یکی از مسئولیت‌ها می‌تواند بدون آنکه متوجه شویم بر سایر مسئولیت‌ها تاثیر بگذارد.

هدف:

هدف اصلی این قانون جدا کردن رفتارها است تا اگر خطایی بر اثر تغییراتی که انجام داده‌ایم ایجاد شود، بر سایر رفتارهایی که به آن مرتبط نیستند تاثیری نداشته باشد.

 

O — Open-Closed اصل باز و بسته

Open–closed principle

کلاس‌ها باید برای گسترش باز باشند اما برای اصلاحات بسته باشند. تغییر رفتار فعلی یک کلاس بر تمام سیستم‌هایی که از آن کلاس استفاده می‌کنند اثر می‌گذارد.

اگر می‌خواهید کلاس توابع بیشتری را اجرا کند روش ایده‌آل این است که آنها را به توابعی که از قبل موجود است اضافه کنید، نه اینکه آنها را تغییر دهید.

هدف:

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

 

L — Liskov Substitution جایگزینی لیسکوف

Liskov substitution principle

اگر S یک زیر گروه از T باشد، آنگاه اشیاء از نوع T در یک برنامه ممکن است با اشیایی از نوع S جایگزین شوند، بدون اینکه هیچ یک از خصیصه‌های خوب آن برنامه را تغییر دهند. هنگامی که یک کلاس فرزند نمی‌تواند همان اقدامات کلاس والد خود را انجام دهد، این می تواند باعث ایجاد خطا و اشکال شود. اگر یک کلاس داشته باشید و کلاس دیگری از آن ایجاد کنید، آن کلاس تبدیل به والد و کلاس جدید تبدیل به یک فرزند می‌شود. کلاس فرزند باید بتواند هر کاری را که کلاس والد انجام می‌دهد انجام دهد، این پروسه "وراثت" نام دارد.

تصویر نشان می‌دهد که کلاس والد قهوه را تحویل می‌دهد (می‌تواند هر نوع قهوه‌ای باشد)، تحویل دادن کاپوچینو برای کلاس فرزند قابل قبول است زیرا یک نوع خاصی از قهوه است، اما تحویل آب قابل قبول نیست. اگر کلاس فرزند این اصول را رعایت نکند، به این معناست که کلاس فرزند به طور کامل تغییر کرده و این اصل را نقض کرده است.

هدف:

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

 

 I — Interface Segregation جداسازی رابط

Interface segregation principle

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

هدف:

هدف این اصل تقسیم گروهی از عملکردها به مجموعه‌های کوچکتر است به صورتی که یک کلاس فقط مجموعه‌ای از اقدامات مورد نیاز خود را اجرا کند.

 

D — Dependency Inversion وارونگی وابستگی

Dependency inversion principle

- ماژول‌های سطح بالا نباید به ماژول‌های سطح پایین وابسته باشند، هر دو باید به انتزاع بستگی داشته باشند.

- انتزاع ها نباید به جزئیات بستگی داشته باشند، جزئیات باید به انتزاعات بستگی داشته باشد.

ابتدا، اجازه دهید اصطلاحات استفاده شده در اینجا را ساده تر تعریف کنیم:

ماژول (یا کلاس) سطح بالا: کلاسی که یک عمل را با یک ابزار اجرا میکند.

ماژول (یا کلاس) سطح پایین: ابزاری که برای اجرای عمل مورد نیاز است.

Abstraction: یک رابط است که دو کلاس را به هم متصل میکند.

جزئیات: چگونه ابزار کار میکند

این اصل می‌گوید که یک کلاس نباید با ابزاری که برای اجرای یک عمل استفاده میکند ترکیب شود، بلکه باید با رابطی که به ابزار اجازه می‌دهد به کلاس متصل شود ترکیب شود.

گفته شده است که هم کلاس و هم رابط کاربری، نباید بدانند ابزار چگونه کار میکنند. با این حال ابزار باید مشخصه‌ها و نیازهای رابط را برآورده کنند.

هدف

هدف این اصل کم کردن وابستگی یک کلاس سطح بالا به کلاس سطح پایین با معرفی یک رابط است.

خلاصه
تا اینجا این پنج اصل را مورد بحث قرار داده‌ایم و اهداف آنها را مشخص کرده‌ایم، این اصول به شما کمک می‌کنند تا کد خود را به راحتی و بدون هیچ مشکلی، اصلاح و آزمایش کنید و گسترش دهید.

خیلی ممنون که این مقاله را مطالعه کردید. امیدوارم درک بهتری در مورد این موضوع داشته باشید و از خواندن آن به همان اندازه که من از نوشتن آن لذت برده‌ام لذت برده باشید.