البرمجة الوصفية في جافا: من الانعكاس إلى توليد الكود
\n\nتخيل أنك تكتب برنامجًا يكتب البرامج بنفسه. أو على الأقل، يحلل نفسه، ويعدل سلوكه أثناء التشغيل، ويُنشئ فئات جديدة دون تدخلك. يبدو كالسحر؟ مرحبًا بك في عالم البرمجة الوصفية في جافا.
\n\nيعتقد العديد من المطورين، عند انتقالهم من اللغات الديناميكية (Python, Ruby)، أن جافا ثابتة جدًا. لكن هذا مفهوم خاطئ. جافا ليست مجرد مترجم و JVM. إنها ترسانة كاملة من الأدوات التي تتيح لك كتابة كود يعمل مع الكود. اليوم سنناقش التقنيات المتقدمة للبرمجة الوصفية التي ستحولك من مطور جافا عادي إلى "ساحر بايت كود" حقيقي.
\n\nهذه المقالة مخصصة لمن أتقن أساسيات جافا ويريد فهم كيفية عمل الأطر مثل Spring أو Hibernate أو Lombok. لن نعيد سرد الوثائق - فقط كود حي، أمثلة حقيقية، وشروحات واضحة.
\n\n1. الانعكاس (Reflection) - عيون برنامجك
\n\nالانعكاس في جافا هو أساس أي برمجة وصفية. إنها قدرة البرنامج على فحص نفسه أثناء التنفيذ. يمكنك معرفة الطرق الموجودة في الكائن، والحقول، والتعليقات التوضيحية المرتبطة بها - وكل ذلك دون معرفة الأنواع في مرحلة التجميع.
\n\nكيف يعمل عمليًا
\n\nلنفترض أن لدينا فئة بسيطة:
\n\npublic class User {\n private String name;\n private int age;\n\n public User(String name, int age) {\n this.name = name;\n this.age = age;\n }\n\n private void secretMethod() {\n System.out.println("لقد استدعيت طريقة خاصة!");\n }\n\n public String getName() { return name; }\n public int getAge() { return age; }\n}\n\nباستخدام الانعكاس، يمكننا "الدخول" إلى داخل هذه الفئة واستدعاء الطريقة الخاصة. نعم، تلك التي تم وضع علامة private عليها.
import java.lang.reflect.Method;\n\npublic class ReflectionDemo {\n public static void main(String[] args) throws Exception {\n User user = new User("أليس", 30);\n\n // الحصول على كائن الفئة\n Class<?> userClass = user.getClass();\n\n // العثور على الطريقة الخاصة بالاسم\n Method secretMethod = userClass.getDeclaredMethod("secretMethod");\n\n // إزالة حماية الوصول\n secretMethod.setAccessible(true);\n\n // استدعاء الطريقة\n secretMethod.invoke(user); // سيطبع: "لقد استدعيت طريقة خاصة!"\n }\n}\n\nرائع، أليس كذلك؟ لكن مع القوة العظيمة تأتي مسؤولية كبيرة. الانعكاس أداة قوية لكنها بطيئة. استخدمها حيثما كان ذلك ضروريًا حقًا: في الأطر، أدوات الاختبار، عند إنشاء ORM.
\n\n2. الوكلاء الديناميكيون (Dynamic Proxies) - معترضو الاستدعاءات
\n\nالوكلاء الديناميكيون في جافا يسمحون لك بإنشاء كائن غلاف يعترض جميع استدعاءات الطرق. هذا هو أساس البرمجة الموجهة نحو الجوانب (AOP) والعديد من آليات التسجيل، التخزين المؤقت، والمعاملات.
\n\nتوفر جافا آلية مدمجة عبر java.lang.reflect.Proxy. تعمل فقط مع الواجهات، لكن هذا ليس قيدًا - في المشاريع الحقيقية، تعمل دائمًا تقريبًا من خلال الواجهات.
مثال: تسجيل جميع الاستدعاءات
\n\nimport java.lang.reflect.InvocationHandler;\nimport java.lang.reflect.Method;\nimport java.lang.reflect.Proxy;\n\n// واجهة\ninterface Calculator {\n int add(int a, int b);\n int multiply(int a, int b);\n}\n\n// تنفيذ حقيقي\nclass SimpleCalculator implements Calculator {\n @Override\n public int add(int a, int b) { return a + b; }\n\n @Override\n public int multiply(int a, int b) { return a * b; }\n}\n\n// معالج الاستدعاءات\nclass LoggingHandler implements InvocationHandler {\n private final Object target;\n\n public LoggingHandler(Object ta