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

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

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

ابدأ الدورة

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

\n\n

مبادئ SOLID هي أساس التصميم الكائني التوجه الذي يساعد المطورين على إنشاء كود مقاوم للتغيير، سهل الاختبار وقابل للتوسع. بالنسبة لمطور Java، فهم هذه المبادئ على المستوى المتقدم ليس مجرد معرفة التعريفات، بل القدرة على رؤية انتهاكاتها في الكود القديم (legacy) وتطبيق أنماط التصميم لإعادة الهيكلة. في هذه المقالة، سنشرح كل مبدأ مع التركيز على المواقف المعقدة والنموذجية.

\n\n

1. مبدأ المسؤولية الواحدة (SRP): الحد الفاصل بين المسؤولية والترابط

\n\n

النظرية: يجب أن يكون للفصل سبب واحد فقط للتغيير. عملياً، هذا يعني أن الفصل يجب أن يكون مسؤولاً عن جزء واحد من وظائف البرنامج.

\n\n

التطبيق المتقدم: غالباً ما يظهر انتهاك SRP ليس في خلط واضح للمنطق، بل في مسؤولية "ضبابية". لنأخذ مثالاً لفصل للتعامل مع التقارير:

\n\n
// انتهاك SRP: الفصل يتعامل مع البيانات والتنسيق والإرسال معاً\npublic class ReportService {\n    public void generateReport(List<Data> data) {\n        // منطق الحسابات\n        Map<String, Integer> aggregated = aggregate(data);\n        // التنسيق (HTML)\n        String html = formatToHtml(aggregated);\n        // الإرسال عبر البريد الإلكتروني\n        sendEmail(html, "admin@example.com");\n    }\n\n    private Map<String, Integer> aggregate(List<Data> data) {\n        // ...\n        return new HashMap<>();\n    }\n\n    private String formatToHtml(Map<String, Integer> data) {\n        // ...\n        return "<html>...</html>";\n    }\n\n    private void sendEmail(String content, String to) {\n        // ...\n    }\n}
\n\n

المشكلة: إذا تغير تنسيق التقرير (مطلوب PDF بدلاً من HTML)، سيتعين تعديل هذا الفصل. إذا تغيرت طريقة الإرسال (Telegram بدلاً من البريد الإلكتروني) — نفس الشيء. الحل هو تقسيمه إلى ثلاثة فصول:

\n\n
public class ReportAggregator {\n    public Map<String, Integer> aggregate(List<Data> data) { ... }\n}\n\npublic class HtmlReportFormatter {\n    public String format(Map<String, Integer> data) { ... }\n}\n\npublic class EmailSender {\n    public void send(String content, String to) { ... }\n}\n\n// التركيب في خدمة\npublic class ReportGenerationFacade {\n    private ReportAggregator aggregator;\n    private HtmlReportFormatter formatter;\n    private EmailSender sender;\n\n    public void generateAndSend(List<Data> data) {\n        var aggregated = aggregator.aggregate(data);\n        var html = formatter.format(aggregated);\n        sender.send(html, "admin@example.com");\n    }\n}
\n\n

2. مبدأ مفتوح-مغلق (OCP): فن التوسع عبر التجريد

\n\n

النظرية: يجب أن تكون الفصول مفتوحة للتوسع، ولكن مغلقة للتعديل.

\n\n

التطبيق المتقدم: الانتهاك النموذجي هو سلاسل if-else أو switch لأنواع مختلفة من الكائنات. الطريقة المتقدمة هي استخدام الإستراتيجية أو القالب مع تعدد الأشكال.

\n\n
// انتهاك OCP: عند إضافة نوع دفع جديد، يجب تعديل الفصل\npublic class PaymentProcessor {\n    public void processPayment(String type, double amount) {\n        if ("CREDIT_CARD".equals(type)) {\n            // منطق لبطاقة الائتمان\n        } else if ("PAYPAL".equals(type)) {\n            // منطق لـ PayPal\n        } else if ("BITCOIN".equals(type)) {\n            // منطق لـ Bitcoin\n        }\n    }\n}
\n\n

التصحيح عبر واجهة ومصنع:

\n\n
public interface PaymentMethod {\n    void pay(double amount);\n}\n\npublic class CreditCardPayment implements PaymentMethod {\n    public void pay(double amount) { ... }\n}\n\npublic class PayPalPayment implements PaymentMethod                

المدونات

توصيات الكتب