اصل مسئولیت واحد در جاوا

سلام! زمانی که تازه شروع به کدنویسی میکنید، نوشتن کدی آسان است که کار میکند اما خواندن یا تغییر بعداً سخت است. اینجاست که SOLID Principles وارد می شود! آنها مانند قوانینی هستند که به شما در نوشتن کدهای تمیز و قابل نگهداری کمک می کنند.
تصور کنید ما در حال ساخت یک برنامه اشتراک گذاری سواری هستیم (مانند Uber)
چه می کند جامد ایستادن برای؟
س: مدیر واحد مسئولیت
O: اصل باز/بسته
L: اصل جایگزینی لیسکوف
من: اصل جداسازی رابط
د: اصل وارونگی وابستگی
1. مدیر واحد مسئولیت (SRP)
قانون: یک کلاس باید فقط یک کار را انجام دهد
مشکل: کلاس پربار
کلاسی را در برنامه اشتراکگذاری سواری خود تصور کنید که رزرو سواری، پرداختها و رانندگان رتبهبندی را مدیریت میکند.
class RideService {
void bookRide(){/* Logic for booking ride */}
void processPayment(){/* Logic for process payment */}
void rateDriver(){/* Logic for reviews */}
}
اگر سیستم پرداخت شما تغییر کند، در خطر شکستن کد رزرو سفر هستید.
این بد است!
رفع: تقسیم کار:
class RideBooking {
void bookRide(){/* Only handles booking ride */}
}
class PaymentService{
void processPayment(){/* Only handles payment process */}
}
class DriverRating{
void rateDriver(){/* Only handle reviews */}
}
اکنون، اگر مشکلی در پرداختها پیش بیاید، رزرو سواری را مختل نمیکند.
هرکس به کار خود پایبند است!
2. اصل باز/بسته
قانون: کلاس ها باید برای تمدید باز باشند اما برای اصلاح بسته شوند
مشکل: سیستم پرداخت شما در ابتدا فقط از پرداخت های کارت اعتباری پشتیبانی می کند. افزودن پشتیبانی برای PayPal مستلزم تغییر کد موجود است که می تواند باگ هایی را ایجاد کند.
class PaymentProcesser{
double processPayments(String type){
if(type.equals("CrediCard")){
return 90.0;
}else if (type.equals("PayPal")){
return 90.0;
}
return 0.0;
}
}
رفع: از یک رابط برای توسعه سیستم بدون تغییر کد موجود استفاده کنید.
interface PaymenTMetod{
double processPayment();
}
class CrediCardPayment implements PaymentMethod{
public double processPayment() { return 90.0; }
}
class PayPalPayment implements PaymentMethod{
public double processPayment() { return 95.0; }
}
class PaymentProcessor{
double process(PaymentMethod payment){
return payment.processPayment();
}
}
3. اصل جایگزینی لیسکوف
قانون: اگر چیزی با کلاس والدین کار می کند،
همچنین باید با کلاس های فرزند خود کار کند
مشکل: وسایل نقلیه غیر قابل پیش بینی
برنامه شما به افراد امکان می دهد ماشین، دوچرخه یا کامیون رزرو کنند.
اما یک روز، یک نفر سعی می کند یک کامیون را برای سوار شدن رزرو کند،
و برنامه از کار می افتد.
چرا؟ چون قرار نیست کامیون ها مسافر ببرند.
class Vehicle {
void startRide() { System.out.println("Ride started"); }
}
class Truck extends Vehicle {
@Override
void startRide() {
throw new UnsupportedOperationException("Trucks can't be booked");
}
}
وقتی از Truck مانند هر وسیله نقلیه دیگری استفاده می کنید، آن طور که انتظار می رود کار نمی کند.
رفع:
بیایید اطمینان حاصل کنیم که هر نوع وسیله نقلیه همانطور که باید رفتار می کند.
abstract class Vehicle {
abstract void startRide();
}
class Car extends Vehicle {
void startRide() { System.out.println("Car ride started"); }
}
class Bike extends Vehicle {
void startRide() { System.out.println("Bike ride started"); }
}
اکنون، تنها وسایل نقلیه ای که می توانند سوار شوند، بخشی از این سیستم هستند. همه عادلانه بازی می کنند!
4. اصل جداسازی رابط
قانون: یک کلاس نباید مجبور به پیاده سازی متدهایی شود که استفاده نمی کنند.
مشکل: مسئولیت های خیلی زیاد
رانندگان در برنامه شما می توانند سواری بپذیرند و درآمد را ببینند،
در حالی که ادمین ها می توانند درایورها را مدیریت کنند.
اگر به هر دو یک رابط بدهید، به نظر می رسد:
interface AppUser {
void acceptRide();
void viewEarnings();
void manageDrivers();
}
رانندگان رانندگان را مدیریت نمی کنند،
بنابراین آنها آن روش را خالی می گذارند یا خطا می دهند. این ناجور است!
رفع: رابط ها را کوچک نگه دارید
interface RideHandler {
void acceptRide();
}
interface EarningsViewer {
void viewEarnings();
}
interface DriverManager {
void manageDrivers();
}
class Driver implements RideHandler, EarningsViewer {
public void acceptRide() { System.out.println("Ride accepted"); }
public void viewEarnings() { System.out.println("Earnings displayed"); }
}
class Admin implements DriverManager {
public void manageDrivers() { System.out.println("Managing drivers"); }
}
در حال حاضر، رانندگان فقط آنچه را که قرار است انجام دهند، و ادمین ها وظایف خود را جداگانه انجام می دهند. همه خوشحال هستند!
5. اصل وارونگی وابستگی
قانون: ماژول سطح بالا نباید به ماژول های سطح پایین بستگی داشته باشد. هر دو باید به انتزاع بستگی داشته باشند.
مشکل: اعلان های کدگذاری شده
برنامه شما اعلانهای پیامکی ارسال میکند، اما اکنون میخواهید ایمیل و اعلانهای فشاری اضافه کنید. کد شما کاملاً با پیامک مرتبط است:
class SMSNotification {
void send(String message) { System.out.println("SMS: " + message); }
}
class NotificationManager {
private SMSNotification smsNotification;
public NotificationManager() {
this.smsNotification = new SMSNotification();
}
void notifyUser(String message) {
smsNotification.send(message);
}
}
برای افزودن ایمیل، باید همه چیز را بازنویسی کنید. چه دردی!
رفع: از یک انتزاع برای جدا کردن مدیر اعلان از روشهای اعلان خاص استفاده کنید.
interface NotificationService {
void send(String message);
}
class SMSNotification implements NotificationService {
public void send(String message) { System.out.println("SMS: " + message); }
}
class EmailNotification implements NotificationService {
public void send(String message) { System.out.println("Email: " + message); }
}
class NotificationManager {
private NotificationService notificationService;
public NotificationManager(NotificationService notificationService) {
this.notificationService = notificationService;
}
void notifyUser(String message) {
notificationService.send(message);
}
}
اکنون می توانید به راحتی بین پیامک، ایمیل یا هر روش اعلان دیگری جابجا شوید.
چرا شما باید مراقبت
پیروی از اصول SOLID کد شما را می سازد:
آسان برای درک (بدون کد “اسپاگتی” کثیف).
به روز رسانی آسان (افزودن ویژگی ها بدون ترس).
کار کردن با آن سرگرم کننده است (به طور جدی، خود آینده شما از شما تشکر خواهد کرد).
بنابراین دفعه بعد که یک برنامه می سازید یا کد می نویسید، این پنج اصل را به خاطر بسپارید. آنها شما را به باهوش ترین کدنویس در اتاق تبدیل می کنند – و چه کسی این را نمی خواهد؟
به نظر شما کدام اصل جالب ترین است؟ به من خبر بده!