مقدمة
في هذا الفصل ، سنشرح الفصل الرابع من تنفيذ المبادئ الخمسة الرئيسية لـ JavaScript الصلبة ، مبدأ فصل الواجهة.
النص الإنجليزي الأصلي:
ملاحظة: مؤلف هذا المقال مؤثر للغاية ، لذلك يعاني العم أيضًا من الاكتئاب لفهمه. فقط اقرأها كما يحلو لك ، لا تتعثر فيها.
وصف مبدأ عزل الواجهة هو:
نسخة الكود كما يلي:
لا ينبغي إجبار العملاء على الاعتماد على الأساليب التي لا يستخدمونها.
لا ينبغي إجبار العملاء على الاعتماد على الأساليب التي لا يستخدمونها.
عندما يتم استخدام طريقة الواجهة التي يعتمد عليها المستخدم فقط من قبل المستخدمين الآخرين ولا يستخدمها ، يجب أن تنفذ هذه الواجهات. بمعنى آخر ، إذا كان المستخدم يعتمد على واجهة غير مستخدمة ولكن المستخدمة من قبل المستخدمين الآخرين ، عندما يعدل المستخدمون الآخرون الواجهة ، سيتأثر جميع المستخدمين الذين يعتمدون على الواجهة. من الواضح أن هذا ينتهك مبدأ الفتح والإغلاق ، وليس ما نتوقعه.
مبدأ عزل الواجهة ISP يشبه إلى حد ما المسؤولية الفردية. كلاهما يستخدم لتجميع المسؤوليات الوظيفية. في الواقع ، يمكن فهم ISP لتحويل البرامج بمسؤوليات واحدة إلى كائن مع واجهة عامة.
واجهة JavaScript
كيف نلتزم بهذا المبدأ تحت جافا سكريبت؟ بعد كل شيء ، لا تحتوي JavaScript على ميزة الواجهات. إذا كانت الواجهة هي ما نريد إنشاء العقد ونفصل عن الأنواع التجريدية التي توفرها لغة معينة ، فيمكن القول أنها على ما يرام ، لكن JavaScript لديها شكل آخر من الواجهة. في أنماط تصميم الكتب ، فإن عناصر البرمجيات الموجهة للكائنات القابلة لإعادة الاستخدام ، وجدنا تعريف الواجهة:
http://www.amazon.com/design-patterns-elements-reusable-object-orieded/dp/0201633612
تحتوي أي عملية معلنة بواسطة كائن على اسم عملية وكائن المعلمة وقيمة الإرجاع للعملية. نسميها توقيع المشغل.
تسمى جميع العمليات المعلنة في كائن واجهة هذا الكائن. تصور واجهة الكائن جميع معلومات الطلب التي تحدث على هذا الكائن.
بغض النظر عما إذا كانت اللغة توفر بنية منفصلة لتمثيل واجهة ، فإن جميع الكائنات لها واجهة ضمنية تتكون من جميع الخصائص وطرق الكائن. الرجوع إلى الكود التالي:
نسخة الكود كما يلي:
var examplinder = {} ؛
examplinder.modelobserver = (function () {
/* متغير خاص*/
يعود {
مراقبة: وظيفة (نموذج) {
/* شفرة*/
إرجاع Newmodel ؛
} ،
OnChange: وظيفة (رد الاتصال) {
/* شفرة*/
}
}
}) () ؛
examplinder.viewAdaptor = (function () {
/* متغير خاص*/
يعود {
Bind: Function (model) {
/* شفرة*/
}
}
}) () ؛
examplinder.bind = function (model) {
/* متغير خاص*/
examplinder.modelobserver.onchange (/ * callback callback */) ؛
var om = examplebinder.modelobserver.observe (model) ؛
examplinder.viewAdaptor.bind (om) ؛
إرجاع OM ؛
} ؛
تقوم مكتبة فئة مثال أعلاه بتنفيذ ربط ثنائي الاتجاه. الواجهة العامة التي تعرضها مكتبة الفئة هذه هي طريقة الربط ، حيث يتم تنفيذ وظائف الإخطار التغيير وتفاعل العرض المستخدمة في الربط بواسطة كائنات منفصلة ModelObserver و ViewAdaptor ، على التوالي. هذه الكائنات هي إلى حد ما التنفيذ المحدد لطريقة ربط الواجهة العامة.
على الرغم من أن JavaScript لا يوفر أنواع الواجهة لدعم عقود الكائنات ، إلا أنه لا يزال من الممكن توفير الواجهة الضمنية للكائن لمستخدمي البرنامج كعقد.
ISP و JavaScript
بعض الأقسام الفرعية التي نناقشها أدناه هي تأثير انتهاك مبدأ عزل الواجهة في JavaScript. كما هو موضح أعلاه ، على الرغم من أنه من المؤسف تنفيذ مبدأ عزل الواجهة في برامج JavaScript ، إلا أنه ليس قويًا مثل اللغات المكتوبة بشكل ثابت. إن خصائص اللغة لـ JavaScript أحيانًا تجعل ما يسمى الواجهة غير لاصقة قليلاً.
تحقيق الفساد
في اللغات المكتوبة بشكل ثابت ، فإن أحد أسباب انتهاك مبادئ مزود خدمة الإنترنت هو التنفيذ المتدفق. يجب تنفيذ الطرق المحددة في جميع الواجهات في Java و C#. إذا كنت بحاجة فقط إلى عدد قليل منها ، فيجب تنفيذ الأساليب الأخرى أيضًا (يمكن تنفيذها عن طريق استثناءات فارغة أو رمي). في JavaScript ، إذا كانت هناك حاجة فقط إلى بعض الواجهات الموجودة في كائن ، فلا يمكن حل مشكلة التنفيذ المتدهورة ، على الرغم من عدم وجود حاجة لفرض تنفيذ الواجهة أعلاه. ومع ذلك ، لا يزال هذا التنفيذ ينتهك مبدأ استبدال ريختر.
نسخة الكود كما يلي:
var rectangle = {
المنطقة: وظيفة () {
/* شفرة*/
} ،
رسم: وظيفة () {
/* شفرة*/
}
} ؛
var geometryapplication = {
getlargestrectangle: وظيفة (مستطيلة) {
/* شفرة*/
}
} ؛
var drawingapplication = {
DrawRectangles: وظيفة (مستطيلات) {
/* شفرة*/
}
} ؛
عندما يكون هناك بديل مستطيل لإرضاء زانق getlargestrect من نوع هندسة الكائن الجديد ، فإنه يحتاج فقط إلى طريقة المستطيل () ، لكنه ينتهك LSP (لأنه لا يمكن استخدام طريقة السحب التي لا يمكن استخدامها إلا في طريقة DrawRectangles).
اقتران ثابت
سبب آخر لانتهاكات مزود خدمة الإنترنت في اللغات المكتوبة بشكل ثابت هو اقتران ثابت. في اللغات المكتوبة بشكل ثابت ، تلعب الواجهات دورًا رئيسيًا في برنامج تصميم مقترن بشكل فضفاض. سواء في لغة ديناميكية أو ثابتة ، قد يحتاج كائن في بعض الأحيان إلى التواصل بين العديد من مستخدمي العملاء (مثل الحالة المشتركة). بالنسبة للغات المكتوبة بشكل ثابت ، فإن الحل الأفضل هو استخدام واجهات الأدوار ، مما يسمح للمستخدم بالتفاعل مع الكائن (الذي قد يحتاج إلى أدوار متعددة) باعتباره تنفيذه لفصل المستخدم والسلوك غير المرتبط. لا توجد مشكلة من هذا القبيل في JavaScript ، لأن الكائنات مفصول من خلال المزايا الفريدة للغات الديناميكية.
اقتران الدلالي
أحد الأسباب الشائعة لانتهاك مزود خدمة الإنترنت هو اللغات الديناميكية والمكتوبة بشكل ثابت ، وهو اقتران دلالي. ما يسمى بالاقتران الدلالي هو الترابط ، أي أن سلوك كائن ما يعتمد على كائن آخر ، مما يعني أنه إذا غير المستخدم أحد السلوكيات ، فمن المحتمل أن يؤثر على مستخدم آخر. هذا ينتهك أيضًا مبدأ المسؤولية الفردية. يمكن حل هذه المشكلة من خلال الميراث واستبدال الكائن.
قابلية التوسع
سبب آخر للمشكلة حول قابلية التوسع. سيقدم العديد من الأشخاص أمثلة حول رد الاتصال لإظهار قابلية التوسع (مثل إعدادات رد الاتصال بعد النجاح في AJAX). إذا كانت هذه الواجهة تحتاج إلى تنفيذ وهناك العديد من الطرق المألوفة أو في كائن هذا التنفيذ ، فسيصبح ISP مهمًا للغاية. وهذا يعني أنه عندما تصبح واجهة الواجهة حاجة لتنفيذ العديد من الأساليب ، سيصبح تنفيذها معقدًا للغاية ، وقد يتسبب ذلك في تولي هذه الواجهات مسؤولية غير دائمة. هذه هي الواجهة الدهنية التي نذكرها في كثير من الأحيان.
لخص
تجعل خصائص اللغة الديناميكية في JavaScript تنفيذ واجهات غير لاصقة أقل تأثيرًا من اللغات المكتوبة بشكل ثابت ، لكن مبدأ عزل الواجهة لا يزال له وظيفته في نموذج برمجة JavaScript.