لم يعد كود Java الخاص بك يجب أن يكون مؤلماً: تعرّف على أنماط العمارة
\n\nهل سبق لك أن فتحت مشروع Java قديم خاص بك وشعرت بقشعريرة تسري في عمودك الفقري؟ كلاس يحتوي على 2000 سطر، حيث تنمو if-else مثل الفطر بعد المطر، وأي تغيير يسحب معه سلسلة من الأخطاء؟ مألوف. هذا ما يسمى "الفوضى المعمارية"، والعيش معها يشبه محاولة بناء ناطحة سحاب على أساس من البسكويت.
لكن هناك خبر جيد: أنماط العمارة في Java ليست نظريات كتب معقدة، بل هي قوالب قتالية مجربة. إنها مثل مجموعة Lego: تعرف أي قطعة تضعها في أي مكان - والمبنى (أي التطبيق) يقف بقوة، ويسهل توسيعه، ولا ينهار عند أول رياح التغيير.
\n\nاليوم سنستعرض أهم الأنماط التي ستنقذك حقاً من إعادة كتابة الكود في الليل. بدون حشو، مع أمثلة حية بلغة Java.
\n\nلماذا "العمارة" ليست عن المخططات، بل عن المال
\n\nلنكن صادقين فوراً: قرارات العمارة لا تُتخذ من أجل الجمال. إنها تؤثر على سرعة التطوير، ووقت إطلاق الميزات، وتكلفة الصيانة. وفقاً للدراسات (والخبرة الطويلة)، يمكن لنمط العمارة المختار بشكل صحيح أن يقلل الوقت اللازم لإدخال وظائف جديدة بنسبة 30-50%. والنمط الخاطئ سيرسل المشروع إلى ديون تقنية لسنوات.
\n\nJava لغة صارمة، ذات كتابة ثابتة. إنها لا تغفر "ربما". ولكن لهذا السبب تعمل الأنماط هنا بشكل فعال بشكل خاص. دعنا نلقي نظرة على اللاعبين الرئيسيين.
\n\n1. Singleton: عندما يكون "واحد" جيداً
\n\nالجوهر: يضمن أن يكون للكلاس مثيل واحد فقط، ويوفر نقطة وصول عالمية إليه.
\n\nأين يفيد: الاتصال بقاعدة البيانات، المسجل (Logger)، الذاكرة المؤقتة (Cache)، إعدادات التطبيق. بشكل عام، كل ما يجب أن يعيش في مثيل واحد.
\n\nالتنفيذ الصحيح في Java (قفل مزدوج الفحص)
\n\npublic class DatabaseConnection {\n\n private static volatile DatabaseConnection instance;\n\n private DatabaseConnection() {\n // مُنشئ خاص - لن يقوم أحد بإنشاء كائن ثانٍ\n }\n\n public static DatabaseConnection getInstance() {\n if (instance == null) {\n synchronized (DatabaseConnection.class) {\n if (instance == null) {\n instance = new DatabaseConnection();\n }\n }\n }\n return instance;\n }\n\n public void query(String sql) {\n System.out.println("Executing: " + sql);\n }\n}\n\nلماذا volatile؟ بدونه، في بيئة متعددة الخيوط، قد يرى أحد الخيوط كائنًا غير مكتمل البناء. و synchronized مع الفحص المزدوج يوفر أمان الخيوط والأداء (يتم تفعيل القفل فقط عند الاستدعاء الأول).
2. Factory Method: إنشاء الكائنات بذكاء
\n\nالجوهر: يحدد واجهة لإنشاء كائن، لكنه يسمح للفئات الفرعية بتحديد أي كلاس سيتم إنشاء مثيل له.
\n\nمتى يُستخدم: عندما لا يكون معروفًا مسبقًا أي نوع محدد من الكائنات سيكون مطلوبًا، أو عندما تكون عملية إنشاء الكائن معقدة.
\n\nمثال: مصنع الإشعارات
\n\ninterface Notification {\n void send(String message);\n}\n\nclass EmailNotification implements Notification {\n public void send(String message) {\n System.out.println("Email: " + message);\n }\n}\n\nclass SMSNotification implements Notification {\n public void send(String message) {\n System.out.println("SMS: " + message);\n }\n}\n\nclass NotificationFactory {\n public static Notification createNotification(String type) {\n return switch (type.toLowerCase()) {\n case "email" -> new EmailNotification();\n case "sms" -> new SMSNotification();\n default -> throw new IllegalArgumentException("Unknown type: "