اصل تک مسئولیتی (Single Responsibility Principle)
این اصل به ما میگه که هر کلاسی که توی برنامهی ما وجود داره، باید یک مسئولیت خاص و مشخص داشته. در واقع این کلاس باید فقط و فقط مسئول یک عملکرد توی برنامه باشه.
این جمله رو همه شنیدیم: یک کار انجام بده ولی درست انجام بده!
به مثال زیر دقت کنین:
class User {
public information() {}
public sendEmail() {}
public orders() {}
}
توی این کلاس ما سه تا متد داریم. متد information که اطلاعات کاربر رو برمیگردونه. متد sendMail برای ارسال ایمیل به کاربر و متد orders سفارشهای کاربر رو برمیگردونه.
به نظرتون اگه کلاسی به اسم User داشته باشیم، هدف این کلاس چی هست؟ احتمالاً اطلاعاتی از کاربر رو ذخیره کنه یا نمایش بده. در واقع مسئولیتی در حوزه مربوط به یک کاربر. اگه به کلاس دقت کنیم، میبینیم که توی این کلاس، فقط متد information هست که با کلاس User مرتبط هست و بقیه متدها وظایفی متفاوت با این کلاس دارن.
کلاس User نباید مسئول ارسال ایمیل و یا هندل کردن سفارشات کاربر باشه. در این صورت کلاس ما با عملکردهای ذاتی خودش محصور شده نیست. یعنی کلاس User با یک سری عملکردهای غیرمرتبط آمیخته شده.
این مسئله زمانی مشکلساز میشه که میخوایم کلاس رو گسترش بدیم. مثلاً ایمیلهای مختلف و اختصاصیتر بفرستیم. که آخر کار نمیدونیم این کلاس User هست یا Email !
خب راه حل اینه که عمکردهای اضافی رو از کلاس User جدا و به یک کلاس اختصاصی منتقل کنیم:
class User {
public information() {}
}
class Email {
public send(user: User) {}
}
class Order {
public show(user: User) {}
}
همونطور که میبینید، کلاس User ما خلوتتر، تمیزتر و مرتب تر شد. همچنین توسعه این کلاس و کلاسهای دیگه راحتتر انجام میشه.
نکته: این اصل نه تنها توی سطح کلاسها، بلکه توی سطح متدها و توابع هم میتونه اعمال بشه. برای مثال، متد send زیر این اصل رو نقض کرده:
class Mailer {
public send(text) {
mailer = new Mail();
mailer.login();
mailer.send(text);
}
}
mail = new Mailer;
mail.send('Salut');
متد send مسئول انجام ۲ کار هست: احراز هویت و بعد ارسال ایمیل. همچنین اصل دوم SOLID که قسمت بعد با اون آشنا میشیم هم اینجا نقض شده.
اگه بخوایم این متد رو بهتر بنویسیم و هم از اصل SRP تبعیت کنیم، میتونیم اون رو به این صورت بنویسیم:
class Mailer {
private mailer;
public constructor(mailer) {
this.mailer = mailer;
}
public send(text) {
this.mailer.send(text);
}
}
myEmail = new MyEmailService;
myEmail.login();
mail = new Mailer(myEmail);
mail.send('Salut');
همونطور که میبینیم، متد send فقط کاری رو انجام میده که وظیفه اون هست.
اصول SOLID به زبان ساده - اصل دوم