عكس التحكم

في هندسة البرمجيات، يعد عكس التحكم (IoC)  مبدأ في البرمجة. يعكس IoC تدفق التحكم flow of control مقارنة بتدفق التحكم التقليديtraditional control flow. في IoC ، تتلقى أجزاء مكتوبة خصيصًا custom-written portions من برنامج الكمبيوتر تدفق التحكم من إطار عامgeneric framework. إن هندسة البرمجيات software architectureمع هذا التصميم تعكس التحكم مقارنة بالبرمجة الإجرائية procedural programming التقليدية: في البرمجة التقليدية، الرمز code المخصص الذي يعبر عن الغرض من البرنامج يستدعي callsمكتبات libraries قابلة لإعادة الاستخدام لرعاية المهام العامة generic tasks، ولكن مع عكس التحكم، فهو الإطارframework الذي يستدعي الرمز code المخصصcustom أو الخاص بالمهمة task-specific.

يستخدم عكس التحكم لزيادة نمطيةmodularity البرنامج وجعله قابلاً للتوسيع extensible،  ولديه تطبيقات في البرمجة الشيئيةobject-oriented programming ونماذج البرمجة programming paradigmsالأخرى. استخدم مايكل ماتسونMichael Mattsson هذا المصطلح في أطروحة،  مأخوذة من هناك  بواسطة ستيفانو مازوتشي Stefano Mazzocchiوشاعه في عام 1999 في مشروع مؤسسة برمجيات أباتشي البائدdefunct Apache Software Foundation project ، أفالون-Avalon> ، ثم تم تعميمه في عام 2004 من قبل روبرت سي مارتن Robert C. Martinو مارتن فاولرMartin Fowler .

يرتبط المصطلح بمبدأ انقلاب التبعية dependency inversion principle، ولكنه يختلف عنه، والذي يهتم بفصل التبعياتdecoupling dependencies بين الطبقات عالية المستوى ومنخفضة المستوى high-level and low-level layers من خلال التجريداتabstractions المشتركة. يرتبط المفهوم العام أيضًا بالبرمجة القائمة على الأحداثevent-driven programming من حيث أنه غالبًا ما يتم تنفيذه باستخدام IoC ، بحيث لا يهتم الرمز المخصصcustom code عادة إلا بمعالجة الأحداث handling of events، في حين يتم التعامل مع حلقة الأحداث event loopوإرسال dispatchالأحداث / الرسائل من خلال الإطارframework أو بيئة وقت التشغيل runtime environment..

 نظرة عامة 
كمثال، مع البرمجة التقليدية، قد تقوم الوظيفة الرئيسية main functionللتطبيق بإجراء استدعاءات وظيفية في قائمة مكتبة menu library لعرض قائمة بالأوامر commands المتاحة والاستعلام query عن المستخدم لاختيار واحد.Dependency Injection.  وبالتالي ستعيد المكتبة الخيار الذي تم اختياره كقيمة استدعاء الدالة the value of the function call، وتستخدم الدالة الرئيسية main function هذه القيمة لتنفيذ الأمر المرتبطexecute the associated command.. كان هذا النمط شائعًا في الواجهات القائمة على النصtext based interfaces . على سبيل المثال، قد يعرض عميل البريد الإلكتروني email client شاشة تحتوي على أوامر لتحميل بريد جديد، والإجابة على البريد الحالي، وبدء بريد جديد، وما إلى ذلك، وسيحظر تنفيذ البرنامج حتى يضغط المستخدم على مفتاح key لتحديد أمرcommand.

مع عكس التحكم inversion of control، من ناحية أخرى، سيتم كتابة البرنامج باستخدام إطار برنامجsoftware framework يعرف العناصر السلوكية common behavioral والرسوم البيانية الشائعة graphical elements ، مثل أنظمة النوافذ windowing systems والقوائم menusوالتحكم في الفأرة controlling the mouse وما إلى ذلك. الرمز المخصصcustom code «يملأ الفراغات» للإطارframework ، مثل توفير جدول عناصر القائمة menu items وتسجيل روتين فرعيregistering a code subroutine لكل عنصرitem ، ولكن الإطارframework الذي يراقبmonitors إجراءات المستخدمuser's actions ويستدعي الروتين الفرعي invokes the subroutine عند تحديد عنصر قائمة menu item. في مثال عميل البريدmail client ، يمكن أن يتبع الإطار كلاً من إدخالات لوحة المفاتيح والفأرة ويستدعي الأمر الذي يستدعيهinvoked المستخدم بأي من الوسائل، وفي الوقت نفسه يراقبmonitor واجهة الشبكة network interfaceلمعرفة ما إذا كانت الرسائل الجديدة تصل وتحديث الشاشة refresh the screen عندما تم الكشفdetected عن نشاط الشبكة network activity. يمكن استخدام نفس الإطارframework كالهيكل العظميskeleton لبرنامج جداول البيانات spreadsheet programأو محرر النصوص text editor. على العكس من ذلك، لا يعرف الإطار شيئًا عن متصفحات الويب أو جداول البيانات أو محرري النصوص؛ يتطلب تنفيذ وظائفهمfunctionality رمزًا مخصصًاcustom code.

إن انعكاس التحكم يحمل دلالة قوية strong connotation على أن الكود القابل لإعادة الاستخدام والرمز الخاص بالمشكلة problem-specific يتم تطويرهما بشكل مستقل على الرغم من أنهما يعملان معًا في تطبيق. إطار عمل Software frameworks، الاسترجاعات callbacks، المنظمونschedulers ، حلقات الحدث<a event loops ، حقن التبعيةdependency injection ، وطريقة قالب <template method> أمثلة من أنماط التصميمdesign patterns التي تتبع مبدأ انعكاس السيطرة inversion of control principle، ايضاً المصطلح أكثر شيوعا في سياق البرمجة كائنية التوجه object-oriented programming. .

يخدم عكس التحكم Inversion of control اهداف التصميم design التالية:

 فصلdecouple تنفيذ المهمة execution of a task عن التنفيذimplementation.
 لتركيز الوحدة النمطية module على المهمة المصممة لها.
 لتحرير الوحدات النمطية free modulesمن الافتراضات assumptions حول كيفية قيام الأنظمة الأخرى بما تفعله وبدلاً من ذلك تعتمد على العقود contracts.
 لمنع الآثار الجانبية side effectsعند استبدال الوحدة module.

أحيانًا ما يُشار إلى انقلاب السيطرة بشكل ظاهري باسم «مبدأ هوليوود: لا تتصل بنا، نحن من سيتصل بك».

 خلفية 
إن عكس التحكم ليس مصطلحًا جديدًا في علوم الكمبيوتر. يتتبع مارتن فاولرMartin Fowler أصل العبارة حتى عام 1988، Inversion of Control on Martin Fowler's Bliki  ولكنها ترتبط ارتباطًا وثيقًا بمفهوم عكس البرنامج program inversionالذي وصفه مايكل جاكسونMichael Jackson في منهجيتهmethodology في البرمجة جاكسون المنظمة<a Jackson Structured Programming> في السبعينيات. يمكن رؤية المحلل من الأسفل إلى الأعلىbottom-up parser على أنه انعكاس للمحلل من أعلى لأسفلtop-down parser : في الحالة الأولى، يقع عنصر التحكم على المحلل اللغوي parser، بينما في الحالة الأخرى، يقع على عاتق تطبيق الاستلام receiving application.

حقن التبعية Dependency injectionهو نوع معين من IoC. يشبه محدد الخدمة <service locator> مثل Java Naming and Directory Interface (JNDI). في مقال كتبه Loek Bergman ،  Inside Architecture: write once, run anywhere by Loek Bergman تم تقديمه كمبدأ معماريarchitectural principle.

في مقال بقلم روبرت سي مارتن Robert C. Martin، The Dependency Inversion principle by Robert C. Martin  يأتي مبدأ انعكاس التبعية dependency inversion principleوالتجريدabstraction عن طريق الطبقات معا layering come together. إن سبب استخدام مصطلح «الانقلاب» inversion بالمقارنة مع طرق تطوير البرمجيات التقليدية. يصف فك ربط الخدماتuncoupling of services عن طريق تجريد الطبقاتabstraction of layers عندما يتحدث عن انعكاس التبعية dependency inversion. يستخدم المبدأ لمعرفة أين توجد حدود النظام في تصميمdesign طبقات التجريدabstraction layers..

 وصف 
في البرمجة التقليدية traditional programming، يتم تحديد تدفق منطق الأعمال the flow of the business logic بواسطة كائناتobjects مرتبطة بشكل ثابت ببعضها"Static binding" statically bound البعض. مع عكس التحكم، يعتمد التدفق flow على الرسم البياني للكائن object graphالذي تم إنشاؤه أثناء تنفيذ البرنامج. مثل هذا التدفق الديناميdynamic flow أصبح ممكنا من خلال تفاعلات الكائن object interactionsالتي يتم تعريفها من خلال التجريدabstractions. يتم تحقيق هذا الربط في وقت التشغيل "run-time binding بواسطة آليات مثل حقن التبعية dependency injection أو محدد مواقع الخدمة service locator. في IoC ، يمكن أيضًا ربط الكود بشكل ثابت linked statically أثناء التجميع compilation، ولكن العثور على الكود ليتم تنفيذه من خلال قراءة وصفه من التكوين الخارجي external configuration بدلاً من مرجع مباشرdirect reference في الكود نفسه.

في حقن التبعية dependency injection، يقترن الكائن objectبالوحدة التابعة بالكائن dependent object or module الذي يحتاجه في وقت التشغيل run time. . لا يمكن عادةً معرفة الكائن المعين particular object الذي سيلبي التبعية satisfy the dependency أثناء تنفيذ البرنامجprogram execution في وقت الترجمةcompile time باستخدام التحليل الثابتcompile time . بينما تم وصفه من حيث تفاعل الكائنobject interaction هنا، يمكن تطبيق المبدأ على منهجيات البرمجة الأخرى إلى جانب البرمجة الموجهة للكائنات object-oriented programming.

لكي يقوم البرنامج الجاريrunning program بربط الكائناتbind objects ببعضها البعض، يجب أن تمتلك الكائنات واجهات متوافقة ompatible interfaces. على سبيل المثال، قد تقوم الفئة class A بتفويض السلوك للواجهة I interfaceالتي يتم تنفيذها بواسطة الفئة class B ؛ يعمل البرنامج على إنشاء A و B ، ثم حقن B في A

 تقنيات التنفيذ 
في البرمجة الشيئية class ، هناك العديد من التقنيات الأساسية لتنفيذ عكس التحكم. وهذه هي:

 استخدام نمط محدد مواقع الخدمة service locator pattern
 استخدام حقن التبعية<dependency injection> ، على سبيل المثال
 حقن المنشئConstructor injection
 حقن المعلمة Parameter injection
 حقن أفضلSetter injection
 حقن الواجهة Interface injection
 استخدام بحث سياقي contextualized lookup
 باستخدام نمط تصميم طريقة القالب <template method design pattern>
 استخدام نمط التصميم الاستراتيجيstrategy design pattern

في مقال أصلي لمارتن فاولرMartin Fowler ، Inversion of Control Containers and the Dependency Injection Pattern by Martin Fowler  تمت مناقشة التقنيات الثلاثة الأولى. في وصف حول عكس أنواع التحكم، IoC Types  تم ذكر النوع الأخير. غالبًا ما يتم إنجاز البحث السياقي contextualized lookupباستخدام محدد مواقع الخدمة service locator

 أمثلة 
معظم الأطرMost frameworks مثل . NET أو Enterprise Java يعرض هذا النمطpattern : public class ServerFacade {
    public <K, V> V respondToRequest(K request) {
        if (businessLayer.validateRequest(request)) {
            Data data = DAO.getData(request);
            return Aspect.convertData(data);
        }
        return null;
    }
} يعطي هذا المخطط التفصيلي الأساسيbasic outline في Java مثالاً على التعليمات البرمجية باتباع منهجية IoC. من المهم، مع ذلك، أن فيServerFacade  يتم إجراء الكثير من الافتراضاتassumptions حول البياناتdata التي يتم إرجاعهاreturned بواسطة كائن الوصول إلى البيانات object (DAO).
على الرغم من أن كل هذه الافتراضات قد تكون صالحة في وقت ما، إلا أنها ترتبط ب ServerFacade لتنفيذ DAO. سيؤدي تصميم التطبيق بطريقة قلب التحكم إلى تسليم عنصر التحكم بالكامل hand over the control completelyإلى DAO object. ثم يصبح الكود code

public class ServerFacade {
  public <K, V> V respondToRequest(K request, DAO dao) {
    return dao.getData(request);
  }
} يوضح المثال أن الطريقة التي  respondToRequestالطريقة يحدد ما إذا كان IoC مستخدمًا. إنها الطريقة التي يتم بها استخدام المعلماتparameters التي تحددdefine IoC IoC. يشبه هذا نمط تمرير الرسائل message-passingالذي تستخدمه بعض لغات البرمجة الشيئية object-oriented programming.

 انظر أيضا 

 برمجة جانبية المنحى
 استمرارية
 روتين المقاطعة
 المراقب
 نمط محدد موقع الخدمة
 إطار عمل
 نموذج الإستراتيجية
 تحويل لغة الأسلوب الموسع

 المراجع 

 روابط خارجية 

 عكس تفسير التحكم ومثال التنفيذ

تصنيف:معمارية البرمجيات
تصنيف:جافا (لغة برمجة)
تصنيف:نماذج تصميم البرمجيات
تصنيف:هندسة البرمجيات بالمكونات