JavaRush /مدونة جافا /Random-AR /طريقة سهلة لحقن التبعيات

طريقة سهلة لحقن التبعيات

نشرت في المجموعة
إن حقن التبعية (DI) ليس مفهومًا سهل الفهم، وتطبيقه على التطبيقات الجديدة أو الحالية أكثر إرباكًا. توضح لك جيس سميث كيفية القيام بحقن التبعية بدون حاوية حقن في لغات برمجة C# وJava. طريقة بسيطة لحقن التبعية - 1سأوضح لك في هذه المقالة كيفية تنفيذ حقن التبعية (DI) في تطبيقات .NET وJava. لقد لفت مفهوم حقن التبعية انتباه المطورين لأول مرة في عام 2000، عندما كتب روبرت مارتن مقالًا بعنوان "مبادئ وأنماط التصميم" (المعروف لاحقًا بالاختصار SOLID ). يشير الحرف D في SOLID إلى تبعية الانقلاب (DOI)، والتي أصبحت تُعرف فيما بعد باسم حقن التبعية. التعريف الأصلي والأكثر شيوعًا: عكس التبعية هو عكس الطريقة التي تدير بها الفئة الأساسية التبعيات. استخدمت مقالة مارتن الأصلية الكود التالي لتوضيح اعتماد فئة Copyعلى فئة ذات مستوى أدنى WritePrinter:
void Copy()
	{
	 int c;
	 while ((c = ReadKeyboard()) != EOF)
		WritePrinter(c);
	}
المشكلة الأولى الواضحة هي أنه إذا قمت بتغيير قائمة المعلمات أو أنواع إحدى الطرق WritePrinter، فستحتاج إلى تنفيذ التحديثات أينما كان هناك اعتماد على تلك الطريقة. تزيد هذه العملية من تكاليف الصيانة وتشكل مصدرًا محتملاً للأخطاء الجديدة.
هل أنت مهتم بالقراءة عن جافا؟ انضم إلى مجموعة مطوري جافا !
مشكلة أخرى: لم تعد فئة النسخ مرشحًا محتملاً لإعادة الاستخدام. على سبيل المثال، ماذا لو كنت بحاجة إلى إخراج الأحرف التي تم إدخالها من لوحة المفاتيح إلى ملف بدلاً من الطابعة؟ للقيام بذلك، يمكنك تعديل الفئة Copyعلى النحو التالي (بناء جملة لغة C++):
void Copy(outputDevice dev)
	{
	int c;
	while ((c = ReadKeyboard()) != EOF)
		if (dev == printer)
			WritePrinter(c);
		else
			WriteDisk(c);
	}
على الرغم من إدخال تبعية جديدة WriteDisk، لم يتحسن الوضع (بل تفاقم) بسبب انتهاك مبدأ آخر: "يجب أن تكون الكيانات البرمجية، أي الفئات والوحدات النمطية والوظائف وما إلى ذلك، مفتوحة للتوسيع، ولكنها مغلقة أمامها". تعديل." يشرح مارتن أن عبارات if/else الشرطية الجديدة هذه تقلل من استقرار ومرونة الكود. الحل هو عكس التبعيات بحيث تعتمد أساليب الكتابة والقراءة على Copy. بدلاً من "إظهار" التبعيات، يتم تمريرها عبر المُنشئ. يبدو الكود المعدل كما يلي:
class Reader
	{
		public:
		virtual int Read() = 0;
	};
	class Writer
	{
		public:
		virtual void Write(char) = 0;
	};
	void Copy(Reader& r, Writer& w)
	{
		int c;
		while((c=r.Read()) != EOF)
		w.Write(c);
	}
Copyالآن يمكن إعادة استخدام الفصل بسهولة مع تطبيقات مختلفة لطرق الفصل Readerو Writer. لا يحتوي الفصل Copyعلى أي معلومات حول البنية الداخلية للأنواع Reader، Writerمما يجعل من الممكن إعادة استخدامها مع تطبيقات مختلفة. ولكن إذا كان كل هذا يبدو وكأنه نوع من الهراء بالنسبة لك، فربما توضح الأمثلة التالية في Java وC# الموقف.

مثال في Java وC#

لتوضيح سهولة حقن التبعيات بدون حاوية التبعيات، لنبدأ بمثال بسيط يمكن تخصيصه للاستخدام DIفي بضع خطوات فقط. لنفترض أن لدينا فئة HtmlUserPresentation، عندما يتم استدعاء أساليبها، تقوم بإنشاء واجهة مستخدم HTML. إليك مثال بسيط:
HtmlUserPresentation htmlUserPresentation = new HtmlUserPresentation();
String table = htmlUserPresentation.createTable(rowTableVals, "Login Error Status");
أي مشروع يستخدم رمز الفئة هذا سيكون له تبعية على الفئة HtmlUserPresentation، مما يؤدي إلى مشكلات سهولة الاستخدام وقابلية الصيانة الموضحة أعلاه. يقترح التحسين نفسه على الفور: إنشاء واجهة تحتوي على توقيعات لجميع الطرق المتوفرة حاليًا في الفصل HtmlUserPresentation. فيما يلي مثال على هذه الواجهة:
public interface IHtmlUserPresentation {
	String createTable(ArrayList rowVals, String caption);
	String createTableRow(String tableCol);
	// Оставшиеся сигнатуры
}
بعد إنشاء الواجهة، نقوم بتعديل الفصل HtmlUserPresentationلاستخدامه. بالعودة إلى إنشاء النوع HtmlUserPresentation، يمكننا الآن استخدام نوع الواجهة بدلاً من النوع الأساسي:
IHtmlUserPresentation htmlUserPresentation = new HtmlUserPresentation();
String table = htmlUserPresentation.createTable(rowTableVals, "Login Error Status");
يتيح لنا إنشاء واجهة استخدام التطبيقات الأخرى لـ IHtmlUserPresentation. على سبيل المثال، إذا أردنا اختبار هذا النوع، فيمكننا بسهولة استبدال النوع الأساسي HtmlUserPresentationبنوع آخر يسمى HtmlUserPresentationTest. التغييرات التي تم إجراؤها حتى الآن تجعل اختبار الكود وصيانته وتوسيع نطاقه أسهل، ولكنها لا تفعل شيئًا لإعادة الاستخدام نظرًا لأن جميع HtmlUserPresentationالفئات التي تستخدم النوع لا تزال على علم بوجوده. لإزالة هذه التبعية المباشرة، يمكنك تمرير نوع الواجهة IHtmlUserPresentationإلى المُنشئ (أو قائمة معلمات الطريقة) للفئة أو الطريقة التي ستستخدمها:
public UploadFile(IHtmlUserPresentation htmlUserPresentation)
يتمتع المنشئ UploadFileالآن بإمكانية الوصول إلى جميع وظائف النوع IHtmlUserPresentation، لكنه لا يعرف شيئًا عن البنية الداخلية للفئة التي تنفذ هذه الواجهة. في هذا السياق، يحدث حقن النوع عند إنشاء مثيل للفئة UploadFile. يصبح نوع الواجهة IHtmlUserPresentationقابلاً لإعادة الاستخدام عن طريق تمرير تطبيقات مختلفة إلى فئات أو أساليب مختلفة تتطلب وظائف مختلفة.

الاستنتاج والتوصيات لتوحيد المواد

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

  • قم بتغيير الفئات التي تقوم بإنشاء مثيل لهذا النوع الأساسي مباشرة لاستخدام نوع الواجهة الجديد هذا وتمريره عبر المنشئ أو قائمة المعلمات لطريقة الفئة التي ستستخدمه.

  • قم بإنشاء تطبيق اختبار لاختبار نوع الواجهة هذا. بمجرد إعادة بناء التعليمات البرمجية الخاصة بك، DIسيصبح تنفيذها أسهل، وستلاحظ مدى مرونة تطبيقك من حيث إعادة الاستخدام وقابلية الصيانة.
تعليقات
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION