اگر با برنامه نویسی شئگرا آشنایی داشته باشید احتمالا اسم قوانین solid یا SOLID principles به گوشتان خورده است.
این پنج قانون، دستور العمل هایی هستند که برای تولید، گسترش و نگهداری راحت تر برنامه ها از آنها استفاده میشود. این قوانین توسط مهندس نرم افزار Robert C. Martin فراگیر شد.
در اینترنت مطالب بسیار زیادی در رابطه با قوانین solid یافت میشود، اما به ندرت مطلبی پیدا میکنید که این مفهوم را با تصاویر توضیح داده باشند. این امر باعث سخت تر شدن درک مطلب برای کسانی که مثل من با تصاویر بهتر یاد میگیرند میشود.
بنابراین مهمترین ویژگی این نوشته تصاویریست که هدف هر یک از قوانین را برای درک بهتر به نمایش میگذارند.
همانطور که خواهید دید برخی از این اصول شاید شبیه هم به نظر بیایند، اما یک هدف رو دنبال نمیکنند. میتوان از یک اصل یا قانون پیروی کرد در حالی که قانون دیگری را نادیده گرفته باشیم. حتی اگر مشابه هم باشند.
برای ساده کردن کار، من Class ها رو مثال میزنم اما شما میتونید برای فانکشنها، متدها، و ماژول ها هم ازش استفاده کنید.
تک وظیفه بودن یا Single Responsibility
یک کلاس باید تنها مسئولیت یک کار رو بر عهده داشته باشد
اگر یک کلاس چندین مسئولیت داشته باشد، احتمال ایجاد باگ ها هم بیشتر میشود. به این دلیل که اگر تغییراتی در یکی از وظیفه های کلاس ایجاد کنیم، ممکن است که سایر بخش ها بدون اینکه ما اطلاع داشته باشیم تحت تاثیر قرار بگیرند.
هدف
هدف این اصل تفکیک کردن وظیفه ها است، بنابراین اگر به واسطهی تغییراتی که در کد بوجود میآوریم باگی ایجاد شود، روی سایر بخش ها که وظیفه مرتبطی ندارند تاثیری نمیگذارد.
باز-بسته یا Open-Closed
کلاس ها باید قابل گسترش و توسعه باشند، اما جلوی تغییر آنها را گرفت.
اگر رفتار یک کلاس را تغییر بدهیم، روی تمام بخش هایی از سیستم که از این کلاس استفاده میکنند تاثیر میگذارد.
حالت ایده آل برای این که یک کلاس بتواند کار بیشتری انجام دهد آن است که به آن فانکشنی اضافه کنیم که تا الان وجود نداشته است، نه اینکه فانکشنی را تغییر بدهیم.
هدف
هدف این اصل این است که بتوانید رفتارهای یک کلاس رو گسترش بدهید.بدون اینکه رفتارهای قبلی کلاس تغییر کند. این امر باعث جلوگیری از مشکلات و باگ ها در جاهایی که از این کلاس استفاده شده است میشود.
جانشینی لیسکو یا Liskov Substitution
اگر S را زیر گروه T در نظر بگیریم، بنابراین باید بتوانیم بدون اینکه تغییری در برنامه ایجاد کنیم اجزای T را جایگزین اجزای S در نظر بگیریم.
اگر یک کلاس داشته باشید و کلاس دیگری از روی آن بسازید، به آن کلاس والد میگوییم و کلاس دیگر نیز کلاس فرزند محسوب میشود. کلاس فرزند باید تمام کارهایی که کلاس والد میتواند انجام دهد را انجام دهد. به این فرایند ارث بری میگویند.
کلاس فرزند باید بتواند تمام درخواست ها را مشابه والدش پردازش کند و نتیجه مشابه را برگرداند.
در تصویر میبینید که کلاس والد وظیفه تحویل قهوه(میتونه هر نوعی از قهوه باشه) رو بر عهده دارد. قابل قبول است که کلاس فرزند وظیفه تحویل کاپوچینو را برعهده داشته باشد، زیرا این یک نوع مشخص از قهوه است. اما تحویل آب قابل قبول نیست.
اگر کلاس فرزند نتواند این شرایط رو برآورده کند، به معنی آن است که کاملا تغییر کرده و این قانون را نقض میکند.
هدف
هدف این اصل آن است که بتوان از کلاس والد و فرزند برای انجام یه کار بدون اینکه مشکلی بوجود آید استفاده کرد.
تفکیک رابطها یا Interface Segregation
کلاینتها نباید وابسته به متدهایی باشند که از آنها استفادهای نمیکنند.
هنگامی که یک کلاس شامل action هایی است که برای آن استفادهای ندارند، باعث ایجاد باگ یا غیر قابل استفاده شدن آن کلاس میشوند.
یک کلاس باید کارهایی رو انجام بدهد که برای نقش آن لازم است، بقیه کارها باید به صورت کامل حذف و یا این که به کلاس دیگری که به آن نیاز دارد منتقل شوند.
هدف
هدف این اصل آن است که عملکردها را به بخش های کوچکتری تقسیم کنیم تا یک کلاس تنها عملکردهای مورد نیاز خود را اجرا کند.
وارونگی وابستگی ها یا Dependency Inversion
ماژول های سطح بالا نباید به ماژول های سطح پایین وابستگی داشته باشند. بلکه هر دو باید به سطح انتزاعی وابستگی پیدا کنند.
انتزاع نباید به جزئیات وابستگی داشته باشد، اما جزئیات باید به سطح انتزاع وابستگی داشته باشند.
در ابتدا اجازه بدید که اصطلاحات رو ساده تر تعریف کنیم.
ماژول یا کلاس سطح بالا: کلاسی است که یک عمل را با یک ابزار اجرا میکند.
ماژول یا کلاس سطح پایین: ابزار مورد نیاز برای انجام یک عمل است.
انتزاع: نشان دهنده یک رابط، مابین دو کلاس است.
جزئیات: نحوه کار ابزار است.
این اصل بیان میکند که یک کلاس نباید برای انجام یک کار ابزاری رو درون خودش داشته باشد. بلکه باید با استفاده از interface ها اجازه استفاده از یک ابزار را به کلاس بدهد.
همینطور بیان میکند که کلاس و interface نباید جزئیات نحوه کار ابزار را بدانند.
هدف
این اصل برای کاهش وابستگی یک کلاس سطح بالا به کلاس های سطح پایین با استفاده از interface ها استفاده میشود.
امیدوارم که این مطلب برای شما هم مفید باشه، اگر سوال یا پیشنهادی در این رابطه دارید لطفا در قسمت کامنت ها نظر بدید. ممنون از وقتی که گذاشتید.