مقدمة
في هذا الفصل ، سنشرح الفصل الخامس من تنفيذ المبادئ الخمسة الرئيسية للغة جافا سكريبت الصلبة ، وهي LSP (مبدأ انعكاس التبعية).
النص الإنجليزي الأصلي:
مبدأ انعكاس الاعتماد
وصف مبدأ انعكاس التبعية هو:
A. يجب ألا تعتمد الوحدات النمطية عالية المستوى على الوحدات النمطية ذات المستوى المنخفض. كلاهما يجب أن يعتمد على التجريدات.
يجب ألا تعتمد الوحدات النمطية عالية المستوى على الوحدات النمطية ذات المستوى المنخفض ، وينبغي أن يعتمد كلاهما على التجريد
B. لا ينبغي أن تعتمد التجريدات على التفاصيل. يجب أن تعتمد التفاصيل على التجريدات.
لا ينبغي أن يعتمد الخلاصة على التفاصيل ، يجب أن تعتمد التفاصيل على التجريد
تتمثل القضية الأكثر أهمية في مبدأ انعكاس التبعية في التأكد من أن المكونات الرئيسية للتطبيق أو الإطار مفصل من تفاصيل تنفيذ المكون الأساسي غير المهمة ، مما يضمن أن الأجزاء الأكثر أهمية في البرنامج لا تتأثر بالتغييرات والتعديلات على المكونات منخفضة المستوى.
الجزء الأول من هذا المبدأ يدور حول الاقتران بين الوحدات النمطية عالية المستوى والوحدات المنخفضة المستوى. في بنية القسم التقليدية ، تعتمد الوحدات النمطية عالية المستوى (تغليف المنطق التجاري الأساسي للبرنامج) دائمًا على بعض الوحدات ذات المستوى المنخفض (بعض النقاط الأساسية). عندما يتم تطبيق مبدأ انعكاس التبعية ، يتم عكس العلاقة. على عكس الوحدات النمطية عالية المستوى التي تعتمد على الوحدات النمطية ذات المستوى المنخفض ، فإن انعكاس التبعية يجعل الوحدات النمطية ذات المستوى المنخفض تعتمد على واجهات محددة في الوحدات النمطية عالية المستوى. على سبيل المثال ، إذا كنت ترغب في استمرار البيانات لبرنامج ما ، فإن التصميم التقليدي هو أن الوحدة الأساسية تعتمد على واجهة برمجة التطبيقات للوحدة النمطية الثابتة. بعد إعادة الإعمار وفقًا لمبدأ انعكاس التبعية ، تحتاج الوحدة الأساسية إلى تحديد واجهة API المستمرة ، ثم يحتاج مثيل التنفيذ المستمر إلى تنفيذ واجهة API المحددة بواسطة الوحدة الأساسية.
يصف الجزء الثاني من هذا المبدأ العلاقة الصحيحة بين التجريد والتفاصيل. يعد فهم هذا الجزء أكثر فائدة من خلال فهم لغة C ++ لأن قابلية تطبيقه أكثر وضوحًا.
على عكس بعض اللغات المكتوبة بشكل ثابت ، لا يوفر C ++ مفهومًا على مستوى اللغة لتحديد الواجهات. ما هي العلاقة بين تعريف الطبقة والتنفيذ الطبقي؟ في C ++ ، يتم تعريف الفئات في شكل ملفات الرأس ، والتي تحدد أساليب أعضاء الفئة والمتغيرات التي يحتاجها الملف المصدر إلى تنفيذها. نظرًا لأن جميع المتغيرات والأساليب الخاصة محددة في ملف الرأس ، فيمكن استخدامها لتجريدها وفصلها قبل تفاصيل التنفيذ. يتم تطبيق مفهوم الواجهة من خلال تحديد الأساليب المجردة فقط (يتم استخدام فئة الأساس التجريدي في C ++) لتنفيذ الفئات.
تراجع وجافا سكريبت
نظرًا لأن JavaScript هي لغة ديناميكية ، فليس هناك حاجة إلى التجريد للتفكك. لذلك ، يجب ألا يعتمد التجريد على التفاصيل. لا يكون لهذا التغيير تأثير كبير في JavaScript ، ولكن لا ينبغي أن تعتمد الوحدات النمطية عالية المستوى على الوحدات النمطية ذات المستوى المنخفض ولكن لها تأثير كبير.
عند مناقشة مبدأ انعكاس التبعية في سياق اللغات المكتوبة بشكل ثابت ، تشمل مفاهيم الاقتران الدلالية والمادية. هذا يعني أنه إذا كانت الوحدة النمطية ذات المستوى العالي تعتمد على وحدة منخفضة المستوى ، فهي ليست فقط الأزواج في الواجهة الدلالية ، ولكن أيضًا الواجهة المادية المحددة في الوحدة النمطية الأساسية. بمعنى آخر ، يجب ألا يتم فصل الوحدات النمطية عالية المستوى من مكتبة الطرف الثالث ، ولكن أيضًا من وحدات المستوى المنخفض الأصلي.
لشرح ذلك ، تخيل أن برنامج .NET قد يحتوي على وحدة عالية المستوى مفيدة للغاية تعتمد على وحدة مستمرة منخفضة المستوى. عندما يحتاج المؤلف إلى إضافة واجهة مماثلة إلى واجهة برمجة تطبيقات الثبات ، بغض النظر عما إذا كان يتم استخدام مبدأ انعكاس التبعية أم لا ، لا يمكن إعادة استخدام الوحدات النمطية عالية المستوى في برامج أخرى قبل إعادة تنفيذ الواجهة الجديدة لهذه الوحدة المنخفضة المستوى.
في جافا سكريبت ، يقتصر قابلية تطبيق انعكاس التبعية على الاقتران الدلالي بين الوحدات النمطية عالية المستوى والوحدات المنخفضة المستوى. على سبيل المثال ، يمكن لـ DIP إضافة واجهات حسب الحاجة بدلاً من اقتران الواجهات الضمنية المحددة بواسطة الوحدات النمطية ذات المستوى المنخفض.
لفهم هذا ، دعونا نلقي نظرة على المثال التالي:
نسخة الكود كما يلي:
$ .fn.trackmap = وظيفة (خيارات) {
var defaults = {
/ * الافتراضات */
} ؛
الخيارات = $ .Extend ({} ، الافتراضات ، الخيارات) ؛
var mapoptions = {
المركز: جديد google.maps.latlng (Options.latitude ، Options.longitude) ،
التكبير: 12 ،
maptypeid: google.maps.maptypeid.roadmap
} ،
MAP = جديد google.maps.map (هذا [0] ، mapoptions) ،
pos = new Google.maps.latlng (Options.latitude ، Options.longitude) ؛
var marker = جديد google.maps.marker ({
الموقف: نقاط ،
العنوان: Options.Title ،
أيقونة: Options.icon
}) ؛
marker.setMap (MAP) ؛
Options.feed.update (وظيفة (خط العرض ، خط الطول) {
marker.setmap (null) ؛
var newlatlng = new Google.maps.latlng (latitude ، loncitude) ؛
marker.position = newlatlng ؛
marker.setMap (MAP) ؛
map.setCenter (newlatlng) ؛
}) ؛
إرجاع هذا ؛
} ؛
var updater = (function () {
// خصائص خاصة
يعود {
تحديث: وظيفة (رد الاتصال) {
updateMap = رد الاتصال ؛
}
} ؛
}) () ؛
$ ("#map_canvas"). TrackMap ({
Latitude: 35.044640193770725 ،
خط الطول: -89.98193264007568 ،
أيقونة: 'http://bit.ly/zjngde' ،
العنوان: "رقم التتبع: 12345" ،
التغذية: محدث
}) ؛
في الكود أعلاه ، هناك مكتبة فئة JS صغيرة تقوم بتحويل DIV إلى خريطة لعرض معلومات الموقع التي تم تتبعها حاليًا. تحتوي وظيفة TrackMap على تبعيات 2: واجهة برمجة تطبيقات Google التابعة لجهة خارجية وتغذية الموقع. تتمثل مسؤولية كائن التغذية في استدعاء رد الاتصال على رد الاتصال (متوفر عند التهيئة) عند تحديث موضع الأيقونة وتمريره في خط العرض وخط الطول. يتم استخدام واجهة برمجة تطبيقات خرائط Google لتقديم واجهات.
قد تعتمد واجهة كائن التغذية على التثبيت أو غير مصممة وفقًا لمتطلبات وظيفة TrackMap للتثبيت. في الواقع ، فإن دورها بسيط للغاية ، مع التركيز على تطبيقات مختلفة بسيطة ولا يحتاج إلى الاعتماد كثيرًا على خرائط Google. تقترن دلالات TrackMap بمجلة Google Maps API. إذا كنت بحاجة إلى التبديل إلى مزودي الخريطة المختلفين ، فيجب عليك إعادة كتابة وظيفة TrackMap حتى يمكن أن تتكيف مع مقدمي الخدمات المختلفين.
من أجل قلب الاقتران الدلالي لمكتبة فئة خرائط Google ، نحتاج إلى إعادة كتابة وظيفة TrackMap للتصميم إلى اقتران الدلالي بواجهة ضمنية (تجريدي واجهة مزود الخريطة). نحتاج أيضًا إلى كائن تنفيذ يتم تكييفه مع واجهة برمجة تطبيقات خرائط Google. ما يلي هو وظيفة TrackMap التي تم إعادة تمثيلها:
نسخة الكود كما يلي:
$ .fn.trackmap = وظيفة (خيارات) {
var defaults = {
/ * الافتراضات */
} ؛
الخيارات = $ .Extend ({} ، الافتراضات ، الخيارات) ؛
Options.provider.showmap (
هذا [0] ،
الخيارات.
Options.longitude ،
Options.icon ،
Options.title) ؛
Options.feed.update (وظيفة (خط العرض ، خط الطول) {
Options.provider.updatemap (خط العرض ، خط الطول) ؛
}) ؛
إرجاع هذا ؛
} ؛
$ ("#map_canvas"). TrackMap ({
Latitude: 35.044640193770725 ،
خط الطول: -89.98193264007568 ،
أيقونة: 'http://bit.ly/zjngde' ،
العنوان: "رقم التتبع: 12345" ،
التغذية: محدث ،
مزود: TrackMap.GoogleMapsprovider
}) ؛
في هذا الإصدار ، قمنا بإعادة تصميم وظيفة TrackMap وواجهة مزود الخريطة المطلوبة ، ثم نقلنا تفاصيل التنفيذ إلى مكون googlemapsprovider منفصل ، والذي قد يتم تغليفه بشكل مستقل في وحدة JavaScript منفصلة. إليكم تنفيذ GoogleMapsprovider الخاص بي:
نسخة الكود كما يلي:
trackmap.googlemapsprovider = (function () {
var marker ، خريطة ؛
يعود {
showmap: وظيفة (عنصر ، خط العرض ، خط الطول ، أيقونة ، عنوان) {
var mapoptions = {
المركز: Google.maps.latlng جديد (خط العرض ، خط الطول) ،
التكبير: 12 ،
maptypeid: google.maps.maptypeid.roadmap
} ،
pos = new Google.maps.latlng (خط العرض ، خط الطول) ؛
MAP = جديد google.maps.map (العنصر ، mapoptions) ؛
Marker = جديد google.maps.marker ({
الموقف: نقاط ،
العنوان: العنوان ،
أيقونة: أيقونة
}) ؛
marker.setMap (MAP) ؛
} ،
updatemap: وظيفة (خط العرض ، خط الطول) {
marker.setmap (null) ؛
var newlatlng = new Google.maps.latlng (latitude ، loncitude) ؛
marker.position = newlatlng ؛
marker.setMap (MAP) ؛
map.setCenter (newlatlng) ؛
}
} ؛
}) () ؛
بعد إجراء التغييرات المذكورة أعلاه ، ستصبح وظيفة TrackMap مرنة للغاية ولا تضطر إلى الاعتماد على واجهة برمجة تطبيقات خرائط Google. بدلاً من ذلك ، يمكن استبدال مقدمي الخريطة الآخرين في الإرادة ، أي أنه يمكن تكييف أي مزود خريطة وفقًا لاحتياجات البرنامج.
متى يكون الحقن التبعية؟
إنه غير ذي صلة قليلاً. في الواقع ، غالبًا ما يتم خلط مفهوم حقن التبعية مع مبدأ انعكاس التبعية. لتوضيح هذا الاختلاف ، من الضروري شرح:
حقن التبعية هو شكل خاص من انعكاس التحكم ، والانعكاس يعني كيف يكتسب المكون تبعياته. حقن التبعية يعني: يتم توفير التبعية للمكون ، بدلاً من المكون للحصول على التبعية ، مما يعني إنشاء مثيل للاعتماد ، وطلب التبعية من خلال المصنع ، وطلب التبعية من خلال محدد الخدمة أو المكون نفسه. يركز مبدأ انعكاس التبعية وحقن التبعية على التبعيات ويتم استخدامهما للانعكاس. ومع ذلك ، فإن مبدأ انعكاس التبعية لا يركز على كيفية اكتساب المكونات تبعيات ، ولكن فقط على كيفية فصل الوحدات عالية المستوى من الوحدات النمطية منخفضة المستوى. بمعنى ما ، مبدأ انعكاس التبعية هو شكل آخر من أشكال الانقلاب. هنا ، الانعكاس هو الوحدة النمطية التي تحدد الواجهة (المحددة من المستوى السفلي ، الانعكاس إلى المستوى الأعلى).
لخص
هذا هو آخر مقال من المبادئ الرئيسية الخمسة. في هذه المقالات الخمسة ، نرى كيف يتم تنفيذ صلابة في JavaScript. يتم شرح مبادئ مختلفة من زوايا مختلفة في جافا سكريبت. (ملاحظة العم: في الواقع ، أعتقد أنه على الرغم من أنه غير مناسب بعض الشيء ، من منظور آخر ، فإن المبادئ العامة هي في الواقع هي نفسها بلغات مختلفة.)