برمجة موجهة بالسمات

في الحوسبة؛ البرمجة موجهة بالسمات  هي نمط برمجة يهدف إلى زيادة التركيبية، إذ تسمح بالفصل بين الاهتمامات المتقاطعة. وذلك بإضافة إجراء إضافي (إرشاد) إلى كود موجود دون تعديل الكود نفسه، فبدلًا من التحديد المنفصل الذي يُعدَل فيه الكود من خلال مواصفات «نقطة القطع (pointcut)»، مثل «تسجيل جميع الاستدعاءات الوظيفية للوظائف التي يبدأ اسمها بـ «set». تتيح هذه البرمجة إضافة إجراءات غير أساسية لمنطق الأعمال (مثل التسجيل) إلى البرامج دون تشويش الكود الأساسي للوظيفة. تعد البرمجة الموجهة بالسمات أساسًا لتطوير البرمجيات ذات السمات.

تتضمن البرمجة الموجهة بالسمات التوجه طُرق وأدوات برمجية تدعم نمذجة الاهتمامات على مستوى الكود المصدري، بينما يشير «تطوير البرمجيات ذات السمات» إلى تخصص هندسي كامل.

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

يمثل التسجيل اهتمامًا متقاطعًا لأن إستراتيجية التسجيل تؤثر بالضرورة على كل جزء مسجل من النظام. وبالتالي يتقاطع التسجيل جميع الأصناف والطرق المسجلة.

تحتوي جميع تطبيقات البرمجة الموجهة بالسمات بعض التعبيرات المتقاطعة التي تُغلّف كل اهتمام في مكان واحد. يكمن الاختلاف بين التطبيقات في القوة والآمان وسهولة الاستخدام للبنيات المقدمة. مثلًا، الاعتراضات التي تحدد طرق للتعبير عن شكل محدود للتقاطع، دون الدعم الجيد لسلامة الأنواع أو تصحيح الأخطاء. يملك امتداد AspectJ عددًا من هذه التعبيرات التي يغلفها في صنف خاص، يدعى جانب. مثلًا، يمكن للجانب أن يغير إجراء الكود الأساسي (الجزء غير الجانبي من البرنامج) من خلال تطبيق إرشاد (إجراء إضافي) في نقاط الربط المختلفة (نقاط في البرنامج) المحددة في تقدير الكمي أو استعلام يسمى نقطة القطع (يحدد ما إذا كانت نقطة ربط معينة مطابقة). يمكن للجانب أيضًا إجراء تغييرات هيكلية ثنائية متوافقة للأصناف الأخرى، مثل إضافة أصناف أعضاء أو أصناف آباء.

تاريخيًا 
للبرمجة الموجهة بالسمات العديد من السوابق المباشرة إي1 وإي2: الانعكاس، وبروتوكولات الكائن ميتا، والبرمجة غرضية التوجه، ومرشحات التركيب والبرمجة التكيفية.

طور غريغور كيتشالا وزملاؤه في زيروكس بارك المفهوم الصريح للبرمجة الموجهة بالسمات، وتُبع ذلك بإضافة امتداد البرمجة الموجهة بالسمات AspectJ إلى الجافا. اتبع فريق أبحاث آي بي إم منهجًا للأدوات حول طرق تصميم اللغات، واقترحوا عام 2001 Hyper/J وبيئة معالجة الاهتمامات لكنها لم تشهد استخدامات واسعة.

تستخدم الأمثلة في هذه المقالة AspectJ.

يعتبر خادم أعمال مايكروسوفت أول تطبيق رئيسي للبرمجة الموجهة بالسمات يليه وحدة جافا للأعمال.

الدافع والمفاهيم الأساسية 
عادةً ما يكون الجانب (المظهر) موزّع أو متشابك ككود، مما يصعّب فهمه والحفاظ عليه. يكون موزعًا بحكم الوظيفة (مثل التسجيل) الموزعة على عدد من الوظائف غير المترابطة التي قد تستخدمها، وربما في الأنظمة غير المرتبطة كليًا، أو اللغات مختلفة المصدر... إلخ. هذا يعني أن تغيير التسجيل قد يتطلب تعديل جميع الوحدات المتأثرة. تصبح الجوانب متشابكة، ليس فقط مع الوظيفة الرئيسية للأنظمة المعبر عنها فيها، ولكن أيضًا مع بعضها البعض. وهذا يعني أن تغيير اهتمام واحد يستلزم فهم جميع الاهتمامات المتشابكة أو وجود بعض الوسائل التي تمكننا من استنتاج تأثير التغييرات.

مثلًا، باعتبار لدينا تطبيق مصرفي يتضمن طريقة بسيطة للغاية من الناحية المفاهيمية لتحويل مبلغ من حساب إلى آخر:void transfer(Account fromAcc, Account toAcc, int amount) throws Exception {
  if (fromAcc.getBalance() < amount)
      throw new InsufficientFundsException();

  fromAcc.withdraw(amount);
  toAcc.deposit(amount);
}تتجاهل طريقة التحويل هذه بعض الاعتبارات التي قد يتطلبها التطبيق المستخدم: فهي تفتقر إلى فحوصات الأمان للتحقق من أن المستخدم الحالي لديه الإذن لإجراء هذه العملية؛ ويجب أن تُغلف معاملات قاعدة البيانات العملية لمنع فقدان البيانات العرضي؛ وبالنسبة للتشخيصات، يجب تسجيل العملية في سجل النظام، وما إلى ذلك.

يمكن أن يبدو النص الذي يتضمن جميع هذه الاهتمامات الجديدة كما يلي:void transfer(Account fromAcc, Account toAcc, int amount, User user,
    Logger logger, Database database) throws Exception {
  logger.info("Transferring money...");
  
  if (!isUserAuthorised(user, fromAcc)) {
    logger.info("User has no permission.");
    throw new UnauthorisedUserException();
  }
  
  if (fromAcc.getBalance() < amount) {
    logger.info("Insufficient funds.");
    throw new InsufficientFundsException();
  }

  fromAcc.withdraw(amount);
  toAcc.deposit(amount);

  database.commitChanges();  // Atomic operation.

  logger.info("Transaction successful.");
}في هذا المثال، أصبحت الاهتمامات الأخرى متشابكة مع الوظيفة الأساسية (تسمى أحيانًا «اهتمامات الأعمال المنطقية»). فتمثل كل من المعاملات، والأمان، والتسجيل اهتمامات متقاطعة.

فكّر الآن فيما سيحدث إذا احتجنا فجأةً إلى تغيير اعتبارات الأمان للتطبيق مثلًا. في النسخة الحالية للبرنامج، تبدو العمليات المتعلقة بالأمان موزعة في عدة طرق، ويتطلب تغييرها جهدًا كبيرًا.

تحاول البرمجة الموجهة بالسمات حل هذه المشكلة بالسماح للمبرمج بالتعبير عن الاهتمامات المتقاطعة في وحدات مستقلة التي تسمى الجوانب. يمكن أن تحتوي الجوانب على إرشاد (كود متصل بنقاط محددة في البرنامج) وتصريحات بين الأنواع (أعضاء هيكلية تضاف إلى أصناف أخرى). مثلًا، يمكن أن تتضمن وحدة الأمان إرشادًا يقوم بفحص أمني قبل الوصول إلى حساب مصرفي. تحدد نقطة القطع الأوقات (نقاط الانضمام) التي يمكن للشخص فيها الوصول إلى حساب مصرفي، ويحدد الكود الموجود في جسم الإرشاد كيفية تنفيذ فحص الأمان. بهذه الطريقة، يمكن الاحتفاظ بالتحقق والأماكن في مكان واحد. علاوةً على ذلك، يمكن أن تشير نقطة القطع الجيدة إلى تغييرات لاحقة في البرنامج، وبالتالي إذا أنشأ مطور آخر طريقة جديدة للوصول إلى الحساب المصرفي، فسيطبق الإرشاد على الطريقة الجديدة عند تنفيذها.

لذا يمكن تنفيذ التسجيل للمثال السابق في جانب كالتالي:aspect Logger {
  void Bank.transfer(Account fromAcc, Account toAcc, int amount, User user, Logger logger)  {
    logger.info("Transferring money...");
  }

  void Bank.getMoneyBack(User user, int transactionId, Logger logger)  {
    logger.info("User requested money back.");
  }

  // Other crosscutting code.
}يمكن التفكير في البرمجة الموجهة بالسمات بوصفها أداة لتصحيح الأخطاء أو كأداة على مستوى المستخدم. يجب حفظ الإرشاد للحالات التي لا يمكنك فيها تغيير الوظيفة (مستوى المستخدم) أو لا ترغب في تغيير الوظيفة في كود الإنتاج (تصحيح الأخطاء).

مراجع 

 
أنماط برمجة