JavaRush /جاوا بلاگ /Random-UR /انحصار کو انجیکشن لگانے کا ایک آسان طریقہ

انحصار کو انجیکشن لگانے کا ایک آسان طریقہ

گروپ میں شائع ہوا۔
انحصار انجیکشن (DI) کو سمجھنے کے لیے آسان تصور نہیں ہے، اور اسے نئی یا موجودہ ایپلی کیشنز پر لاگو کرنا اور بھی الجھا ہوا ہے۔ جیس سمتھ آپ کو دکھاتا ہے کہ سی # اور جاوا پروگرامنگ زبانوں میں انجیکشن کنٹینر کے بغیر انحصار انجیکشن کیسے کریں۔ انحصار انجیکشن کا آسان طریقہ - 1اس مضمون میں، میں آپ کو .NET اور Java ایپلیکیشنز میں انحصار انجیکشن (DI) کو لاگو کرنے کا طریقہ دکھاؤں گا۔ انحصار انجیکشن کا تصور سب سے پہلے 2000 میں ڈویلپرز کی توجہ میں آیا، جب رابرٹ مارٹن نے مضمون "ڈیزائن کے اصول اور نمونے" لکھا (بعد میں مخفف SOLID سے جانا جاتا ہے )۔ SOLID میں D سے مراد الٹا انحصار (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، صورت حال بہتر نہیں ہوئی (بلکہ مزید بگڑ گئی) کیونکہ ایک اور اصول کی خلاف ورزی کی گئی تھی: "سافٹ ویئر اداروں، یعنی کلاسز، ماڈیولز، فنکشنز، اور اسی طرح، توسیع کے لیے کھلا ہونا چاہیے، لیکن اس کے لیے بند ترمیم۔" مارٹن وضاحت کرتا ہے کہ یہ نئے مشروط اگر/اور بیانات کوڈ کے استحکام اور لچک کو کم کرتے ہیں۔ حل یہ ہے کہ انحصار کو الٹ دیا جائے تاکہ لکھنے اور پڑھنے کے طریقے پر منحصر ہوں 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، مختلف نفاذ کے ساتھ انہیں دوبارہ استعمال کرنا ممکن بناتا ہے۔ لیکن اگر یہ سب کچھ آپ کو کسی قسم کی گوبلڈیگوک کی طرح لگتا ہے، تو شاید جاوا اور C# میں درج ذیل مثالیں صورتحال کو واضح کردیں گی۔

جاوا اور 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