تصميم C++ الحديث

كتاب " التصميم الحديث بلغة C++: البرمجة العامة وتطبيقات أنماط التصميم" من تأليف أندريه ألكسندرسكو ، ونُشر عام 2001 بواسطة دار نشر أديسون-ويسلي . وقد وصفه سكوت مايرز بأنه "أحد أهم كتب لغة C++". [ 1 ]

يستكشف الكتاب تقنية برمجة C++ تُسمى البرمجة الوصفية للقوالب ، ويتناولها بالتفصيل. ورغم أن ألكسندريسكو لم يخترع هذه التقنية، إلا أنه ساهم في نشرها بين المبرمجين. يحتوي كتابه على حلول لمشاكل عملية قد يواجهها مبرمجو C++. وقد أصبحت عدة مصطلحات من الكتاب شائعة الاستخدام في مجتمع C++، مثل: C++ الحديثة (مقارنةً بأسلوب C/C++)، والتصميم القائم على السياسات ، وقائمة الأنواع .

جميع الشفرات البرمجية المذكورة في الكتاب متاحة مجاناً في مكتبة لوكي الخاصة به . وقد أعيد نشر الكتاب وترجمته إلى عدة لغات منذ عام 2001.

التصميم القائم على السياسات

التصميم القائم على السياسات ، المعروف أيضًا بتصميم الفئات القائم على السياسات أو البرمجة القائمة على السياسات ، هو المصطلح المستخدم في كتاب " التصميم الحديث للغة C++" لوصف منهج تصميم يعتمد على مصطلح "السياسات" في لغة C++ . وقد وُصف بأنه شكلٌ مُعدّلٌ لنمط الاستراتيجية في وقت الترجمة ، ويرتبط ببرمجة القوالب الوصفية في C++ . وقد شاع استخدامه لأول مرة في لغة C++ على يد أندريه ألكسندرسكو من خلال كتابه " التصميم الحديث للغة C++" وعموده "البرمجة العامة" في مجلة مستخدمي C/C++ . ويرتبط هذا المنهج حاليًا ارتباطًا وثيقًا بلغتي C++ و D ، إذ يتطلب مُترجمًا يتمتع بدعم قوي للقوالب ، وهو أمر لم يكن شائعًا قبل عام 2003 تقريبًا.

تتضمن الأمثلة السابقة لهذا النهج التصميمي، القائم على التعليمات البرمجية العامة ذات المعلمات، وحدات نمطية (وظائف) للغات ML ، [ 2 ] ومخصصات C++ لسياسة إدارة الذاكرة.

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

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

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

من عيوب السياسات في شكلها الحالي أن واجهة السياسة لا تملك تمثيلاً مباشراً وصريحاً في الكود ، بل تُعرَّف ضمنياً عبر الكتابة الديناميكية ، ويجب توثيقها بشكل منفصل ويدوي في التعليقات . الفكرة الأساسية هي استخدام تحليل التشابه والاختلاف لتقسيم النوع إلى التنفيذ والواجهة الثابتين، والفئة القائمة على السياسة، والسياسات المختلفة. يكمن التحدي في معرفة مكونات الفئة الرئيسية، والسياسات التي يجب إنشاؤها. تُقدم المقالة المذكورة أعلاه الإجابة التالية: حيثما نحتاج إلى اتخاذ قرار تصميمي مُقيِّد محتمل، يجب تأجيل هذا القرار، وتفويضه إلى سياسة مُسماة بشكل مناسب.

يمكن أن تحتوي فئات السياسات على تفاصيل التنفيذ وتعريفات الأنواع وما إلى ذلك. بشكل أساسي، يحدد مصمم فئة القالب الرئيسية ما يجب أن توفره فئات السياسات، وما هي نقاط التخصيص التي تحتاج إلى تنفيذها.

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

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

يمكن الآن تحقيق ذلك بشكل ديناميكي من خلال المفاهيم [ 3 ] منذ C++20 .

مثال بسيط

فيما يلي مثال بسيط (مصطنع) لبرنامج " مرحباً بالعالم " بلغة C++ ، حيث يتم تقسيم النص المراد طباعته وطريقة طباعته باستخدام السياسات. في هذا المثال، HelloWorldهي فئة مضيفة تأخذ سياستين، إحداهما لتحديد كيفية عرض الرسالة والأخرى للرسالة نفسها المراد طباعتها. لاحظ أن التنفيذ العام موجود في run، وبالتالي لا يمكن تجميع الكود إلا بتوفير كلتا السياستين ( writeو ).message

استيراد std ؛باستخدام std :: string ;template < typename OutputPolicy , typename LanguagePolicy > class HelloWorld : private OutputPolicy , private LanguagePolicy { public : // دالة السلوك. void run () const { // دالتان للسياسة. write ( message ()); } };class WriteToStdout { protected : void write ( string && message ) const { std :: println ( "{}" , message ); } };class EnglishMessage { protected : [[ nodiscard ]] string message () const noexcept { return "Hello, World!" ; } };class GermanMessage { protected : [[ nodiscard ]] string message () const noexcept { return "Hallo Welt!" ; } };int main () { // مثال 1 HelloWorld < WriteToStdout , EnglishMessage > helloWorld ; helloWorld . run (); // يطبع "Hello, World!".// المثال 2 // يقوم بنفس الشيء، لكنه يستخدم سياسة لغة مختلفة. HelloWorld < WriteToStdout , GermanMessage > helloWorld2 ; helloWorld2 . run (); // يطبع "Hallo Welt!". }

يمكن للمصممين بسهولة كتابة المزيد من OutputPolicyالتعليمات البرمجية عن طريق إضافة فئات جديدة مع وظيفة العضو writeوأخذها كتعليمات OutputPolicyبرمجية جديدة.

مكتبة لوكي

Loki هي مكتبة برمجية مكتوبة بلغة C++ بواسطة أندريه ألكسندرسكو كجزء من كتابه Modern C++ Design .

تستخدم المكتبة على نطاق واسع برمجة القوالب الوصفية في لغة C++ وتنفذ العديد من الأدوات الشائعة الاستخدام: قائمة الأنواع ، والدالة ، والنمط الفردي ، والمؤشر الذكي ، ومصنع الكائنات ، والزائر ، والأساليب المتعددة .

في الأصل، كانت المكتبة متوافقة فقط مع اثنين من أكثر مُجمِّعات لغة C++ توافقًا مع المعايير ( CodeWarrior و Comeau C/C++ ): وقد أتاحت الجهود اللاحقة استخدامها مع مجموعة واسعة من المُجمِّعات (بما في ذلك الإصدارات القديمة من Visual C++ 6.0 و Borland C++ Builder 6.0 و Clang و GCC ). استخدم مُصنِّعو المُجمِّعات Loki كمعيار للتوافق، مما زاد من عدد المُجمِّعات المتوافقة. [ 4 ]

استمرت صيانة وتطوير مكتبة Loki من خلال مجتمع مفتوح المصدر بقيادة بيتر كوميل وريتشارد سبوساتو كمشروع على منصة SourceForge. وقد ساهمت المساهمات المستمرة من العديد من الأشخاص في تحسين متانة المكتبة ووظائفها بشكل عام. لم تعد Loki مرتبطة بالكتاب، إذ أنها تتضمن بالفعل العديد من المكونات الجديدة (مثل StrongPtr وPrintf وScopeguard). وقد ألهمت Loki أدوات ووظائف مماثلة موجودة الآن في مجموعة مكتبات Boost .

انظر أيضاً

مراجع

  1. مايرز، سكوت (9 أغسطس 2006). "أهم كتب لغة C++ على الإطلاق" . أرتيما . تم الاطلاع عليه في 8 سبتمبر 2025 .
  2. الفصل 7. الأنواع المجردة والدوال cam.ac.uk
  3. مفاهيم: مستقبل البرمجة العامة stroustrup.com
  4. مؤتمر C++ وما بعده 2011: جلسة "اسألنا أي شيء"، http://channel9.msdn.com/Shows/Going+Deep/C-and-Beyond-2011-Scott-Andrei-and-Herb-Ask-Us-Anything من الدقيقة 51:40 إلى 51:51