3. عكس التحكم IoC
لنركز الآن على مفهوم عكس التحكم (IoC، Inversion of Control) الذي يستخدمه Spring لتكوين التطبيقات. لتوضيح هذا المفهوم، لنعد إلى بنية تطبيق الاختبار السابق:
![]() |
للوصول إلى بيانات SGBD، يجب أن تستخدم فئة الاختبار خدمات كائن يُنفذ واجهة [IArticlesDao]، على سبيل المثال كائن من النوع [ArticlesDaoPlainODBC]. وقد درسنا حلين ممكنين لإنشاء مثيل لمثل هذا الكائن:
- في الحل الأول، كانت فئة الاختبار تطلب بنفسها إنشاء مثيل لكائن من النوع [ArticlesDaoPlainODBC]:
<TestFixture()> _
Public Class NunitTestArticlesDaoPlainOdbc
' الكائن المراد اختباره
Private articlesDao As IArticlesDao
<SetUp()> _
Public Sub init()
' يتم إنشاء مثيل للكائن المراد اختباره
articlesDao = New ArticlesDaoPlainODBC("odbc-firebird-articles", "SYSDBA", "masterkey")
End Sub
...
End Class
يوجد ارتباط ثابت في الكود باسم الفئة. إذا تغيرت فئة تنفيذ الواجهة [IArticlesDao]، فسيتعين تعديل كود الأسلوب [init]. توجد العلاقات التالية بين الكائنات:
![]() |
تقوم الفئة [NunitTestArticlesDaoPlainOdbc] بنفسها بإنشاء الكائن [ArticlesDaoPlainODBC] الذي تحتاجه. وبالعودة إلى مصطلح «انعكاس التحكم»، يمكن القول إنها هي التي تمتلك «التحكم» لإنشاء الكائن الذي تحتاجه.
- أما الحل الثاني فيعمل بطريقة مختلفة. وأصبحت فئة الاختبار كما يلي:
<TestFixture()> _
Public Class NunitSpringTestArticlesDaoPlainOdbc
' الكائن المراد اختباره
Private articlesDao As IArticlesDao
<SetUp()> _
Public Sub init()
' استرداد مثيل من مُنشئ الكائنات Spring
Dim factory As XmlObjectFactory = New XmlObjectFactory(New FileStream("spring-config-plainodbc.xml", FileMode.Open))
' طلب إنشاء مثيل للكائن articles dao
articlesDao = CType(factory.GetObject("articlesdao"), IArticlesDao)
End Sub
...
End Class
يمكن توضيح هذه الآلية كما يلي:
![]() |
هنا، لا تأخذ فئة الاختبار زمام المبادرة في طلب إنشاء كائن [ArticlesDaoPlainODBC]. بل تكتفي بطلب مرجع إلى هذا الكائن من Spring. إذا كان الكائن موجودًا، فإن Spring تعطي مرجعًا إليه. وإذا لم يكن موجودًا، فإنها تقوم بإنشائه. فقدت فئة الاختبار السيطرة على إنشاء الكائن [ArticlesDaoPlainODBC]. فهي تطلب ببساطة مرجعًا لهذا الكائن. سيؤدي هذا الطلب هنا إلى إجبار Spring على إنشاء الكائن. لكن يمكننا أن نتصور، في سياق آخر، أن الكائن المطلوب قد تم إنشاؤه بالفعل بناءً على طلب التطبيق. في هذه الحالة، لا يعيد Spring إنشاء الكائن، بل يقدم مرجعًا إلى الكائن الموجود بالفعل (السينجلتون). ويعني مفهوم «انعكاس التحكم» (IoC) هنا:
- أن التطبيق لا يبادر أبدًا بإنشاء الكائنات الفردية التي يحتاجها. بل يكتفي بطلب الإشارات إليها.
- Spring هو الذي يتخذ قرار إنشاء كائن فريد عند أول طلب للحصول على مرجع له


