مبادئ SOLID في Java: النظرية والتطبيق للمطورين

مدرب بايثون أونلاين للمبتدئين

تعلم Python بسهولة دون إرهاق نظري. حل مهام عملية مع التحقق التلقائي واكتب الكود مباشرة في المتصفح.

ابدأ الدورة

مبادئ SOLID في Java: من النظرية إلى الكود النظيف



كل مطور Java يواجه عاجلاً أم آجلاً مشكلة الكود "القذر": فئات تقوم بكل شيء في آن واحد، تبعيات صلبة، واستحالة التوسع دون كسر المنطق الموجود. هنا تأتي مبادئ SOLID للإنقاذ — خمس قواعد أساسية في التصميم كائني التوجيه، صاغها روبرت مارتن (العم بوب). في هذه المقالة، سنشرح كل مبدأ عملياً مع أمثلة بلغة Java، ليجعل كودك مرناً، قابلاً للاختبار، وسهل الصيانة.



1. مبدأ المسؤولية الواحدة (Single Responsibility Principle - SRP)



الجوهر: "يجب أن يكون للفئة سبب واحد فقط للتغيير". بمعنى آخر، يجب أن تكون الفئة مسؤولة عن مهمة واحدة محددة بوضوح.



انتهاك SRP

لننظر إلى الفئة OrderService التي تقوم في نفس الوقت بحساب السعر، والحفظ في قاعدة البيانات، وإرسال البريد الإلكتروني:



public class OrderService {    public void processOrder(Order order) {        // 1. حساب التكلفة        double total = order.getItems().stream()                .mapToDouble(Item::getPrice)                .sum();

// 2. الحفظ في قاعدة البيانات Database.save(order);

// 3. إرسال الإشعار EmailService.send("تم تأكيد الطلب بقيمة: " + total); }}


المشكلة: تغيير منطق إرسال البريد أو طريقة الحفظ سيؤدي إلى تعديل OrderService. هذا ينتهك مبدأ SRP.



إعادة الهيكلة وفقاً لـ SRP

نقوم بتقسيم المسؤوليات إلى ثلاث فئات منفصلة:



public class PriceCalculator {    public double calculateTotal(Order order) {        return order.getItems().stream()                .mapToDouble(Item::getPrice)                .sum();    }}

public class OrderRepository { public void save(Order order) { Database.save(order); }}

public class NotificationService { public void sendConfirmation(Order order) { EmailService.send("تم تأكيد الطلب بقيمة: " + order.getTotal()); }}

// كود العميلpublic class OrderProcessor { private PriceCalculator calculator; private OrderRepository repository; private NotificationService notifier;

public void processOrder(Order order) { double total = calculator.calculateTotal(order); order.setTotal(total); repository.save(order); notifier.sendConfirmation(order); }}


النتيجة: كل فئة لها سبب واحد للتغيير. يصبح الكود معيارياً وقابلاً للاختبار.



2. مبدأ الانفتاح/الانغلاق (Open-Closed Principle - OCP)



الجوهر: "يجب أن تكون الكيانات البرمجية مفتوحة للتمديد، ولكن مغلقة للتعديل". يتم إضافة الوظائف الجديدة من خلال التوسيع، وليس عن طريق تعديل الكود الموجود.



انتهاك OCP

لنتخيل نظام خصومات، حيث كل نوع جديد من الخصم يتطلب تغيير في الدالة applyDiscount:



public class DiscountService {    public double applyDiscount(String type, double price) {        if (type.equals("SUMMER")) {            return price * 0.9;        } else if (type.equals("VIP")) {            return price * 0.8;        }        // إضافة نوع جديد → تغيير الفئة        return price;    }}


الحل من خلال تعدد الأشكال

نستخدم واجهة وتطبيقات مختلفة:



public interface Discount {    double apply(double price);}

public class SummerDiscount implements Discount { @Override public double apply(double price) { return price * 0.9; }}

public class VipDiscount implements Discount { @Override public double apply(double price) { return price * 0.8; }}

// نوع جديد — مجرد فئة جديدة

المدونات

توصيات الكتب