اصل تک مسئولیتی (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 به زبان ساده - اصل دوم