Dependency inversion principle
آبجیکٹ پر مبنی ڈیزائن میں، انحصار الٹ اصول ڈھیلے جوڑے والے سافٹ ویئر ماڈیولز کے لیے ایک مخصوص طریقہ کار ہے۔ اس اصول پر عمل کرتے وقت، اعلی سطح کے، پالیسی ترتیب دینے والے ماڈیولز سے لے کر نچلے درجے کے، انحصار کرنے والے ماڈیولز تک قائم ہونے والے روایتی انحصار کے تعلقات کو الٹ دیا جاتا ہے، اس طرح اعلی سطح کے ماڈیولز کو نچلے درجے کے ماڈیول کے نفاذ کی تفصیلات سے آزاد کیا جاتا ہے۔ اصول میں کہا گیا ہے: یہ حکم دیتے ہوئے کہ اعلی اور نچلے درجے کی اشیاء کا انحصار ایک ہی تجریدی پر ہونا چاہیے، یہ ڈیزائن اصول جس طرح سے کچھ لوگ آبجیکٹ پر مبنی پروگرامنگ کے بارے میں سوچ سکتے ہیں۔ اس اصول کے نکات اے اور بی کے پیچھے خیال یہ ہے کہ جب اعلی سطحی ماڈیول اور نچلے درجے کے ماڈیول کے درمیان تعامل کو ڈیزائن کرتے ہیں، تو تعامل کو ان کے درمیان ایک تجریدی تعامل کے طور پر سوچا جانا چاہیے۔ اس کا اثر نہ صرف اعلی درجے کے ماڈیول کے ڈیزائن پر پڑتا ہے، بلکہ نچلے درجے کے ماڈیول پر بھی پڑتا ہے: نچلے درجے کے ماڈیول کو تعامل کو ذہن میں رکھتے ہوئے ڈیزائن کیا جانا چاہیے اور اس کے استعمال کے انٹرفیس کو تبدیل کرنا ضروری ہو سکتا ہے۔ بہت سے معاملات میں، اپنے آپ میں تعامل کے بارے میں ایک تجریدی تصور کے طور پر سوچنا اضافی کوڈنگ کے نمونوں کو متعارف کرائے بغیر اجزاء کے جوڑے کو کم کرنے کی اجازت دیتا ہے، جس سے صرف ہلکے اور کم نفاذ پر منحصر تعامل اسکیما کی اجازت ملتی ہے۔ جب دو ماڈیولز کے درمیان دریافت شدہ تجریدی تعامل اسکیما (زبانیں) عام ہوتے ہیں اور عمومی ہونا سمجھ میں آتا ہے، تو یہ ڈیزائن اصول مندرجہ ذیل انحصار الٹ کوڈنگ پیٹرن کی طرف بھی لے جاتا ہے۔ روایتی تہوں کا نمونہ روایتی ایپلی کیشن فن تعمیر میں، نچلی سطح کے اجزاء (مثال کے طور پر، یوٹیلیٹی لیئر) کو اعلی سطح کے اجزاء (مثال کے طور پر، پالیسی لیئر) کے ذریعے استعمال کرنے کے لیے ڈیزائن کیا گیا ہے جو تیزی سے پیچیدہ نظاموں کو بنانے کے قابل بناتے ہیں۔ اس ساخت میں، اعلی سطح کے اجزاء کسی کام کو حاصل کرنے کے لیے براہ راست نچلی سطح کے اجزاء پر انحصار کرتے ہیں۔ نچلی سطح کے اجزاء پر یہ انحصار اعلی سطح کے اجزاء کے دوبارہ استعمال کے مواقع کو محدود کرتا ہے۔ انحصار الٹ پیٹرن کا مقصد ایک تجریدی پرت کی ثالثی کے ساتھ اس انتہائی جوڑی تقسیم سے بچنا، اور اعلی/پالیسی تہوں کے دوبارہ استعمال میں اضافہ کرنا ہے۔ انحصار الٹ پیٹرن ایک تجریدی پرت کے اضافے کے ساتھ، اعلی اور نچلی دونوں سطحیں روایتی انحصار کو اوپر سے نیچے تک کم کرتی ہیں۔ بہر حال، "الٹ" تصور کا مطلب یہ نہیں ہے کہ نچلی سطح کی تہوں کا انحصار براہ راست اعلی سطح کی تہوں پر ہوتا ہے۔ دونوں تہوں کو تجریدی (انٹرفیس) پر انحصار کرنا چاہیے جو اعلی سطح کی تہوں کے لیے درکار رویے کو بے نقاب کرتے ہیں۔ انحصار الٹ کے براہ راست اطلاق میں، خلاصہ اوپری/پالیسی تہوں کی ملکیت ہوتے ہیں۔ یہ فن تعمیر اعلی/پالیسی اجزاء اور تجریدوں کو گروپ کرتا ہے جو ایک ہی پیکیج میں کم خدمات کی وضاحت کرتے ہیں۔ نچلی سطح کی پرتیں وراثت/ان تجریدی کلاسوں یا انٹرفیس کے نفاذ کے ذریعے بنائی جاتی ہیں۔ انحصار اور ملکیت کا الٹا ہونا اعلی/پالیسی تہوں کے دوبارہ استعمال کی حوصلہ افزائی کرتا ہے۔ اوپری پرتیں نچلی خدمات کے دیگر نفاذ کا استعمال کر سکتی ہیں۔ جب نچلی سطح کے پرت کے اجزاء بند ہوتے ہیں یا جب ایپلی کیشن کو موجودہ خدمات کے دوبارہ استعمال کی ضرورت ہوتی ہے، تو یہ عام بات ہے کہ ایڈاپٹر خدمات اور تجریدوں کے درمیان ثالثی کرتا ہے۔ انحصار الٹ پیٹرن کی عمومی کاری بہت سے منصوبوں میں انحصار الٹ اصول اور پیٹرن کو ایک واحد تصور سمجھا جاتا ہے جسے عام کیا جانا چاہیے، یعنی سافٹ ویئر ماڈیولز کے درمیان تمام انٹرفیس پر لاگو کیا جانا چاہیے۔ اس کی کم از کم دو وجوہات ہیں: ایک اچھی سوچ کے اصول کو کوڈنگ پیٹرن کے طور پر دیکھنا آسان ہے۔ ایک بار جب ایک تجریدی کلاس یا انٹرفیس کو کوڈ کیا جاتا ہے، تو پروگرامر کہہ سکتا ہے: "میں نے تجریدی کا کام کر دیا ہے"۔ کیونکہ بہت سے یونٹ ٹیسٹنگ ٹولز مذاق اڑانے کے لیے وراثت پر انحصار کرتے ہیں، کلاسوں کے درمیان عام انٹرفیس کا استعمال (نہ صرف ماڈیولز کے درمیان جب عام استعمال کرنا سمجھ میں آتا ہے) اصول بن گیا۔ اگر استعمال کیا جانے والا مذاق کا آلہ صرف وراثت پر منحصر ہے، تو انحصار الٹ پیٹرن کو بڑے پیمانے پر لاگو کرنا ضروری ہو سکتا ہے۔ اس میں بڑی خرابیاں ہیں: صرف ایک کلاس پر انٹرفیس کو لاگو کرنا جوڑے کو کم کرنے کے لیے کافی نہیں ہے۔ صرف تعاملات کے ممکنہ خلاصہ کے بارے میں سوچنا کم جوڑے والے ڈیزائن کا باعث بن سکتا ہے۔ کسی پروجیکٹ میں ہر جگہ عام انٹرفیس کو نافذ کرنے سے اسے سمجھنا اور برقرار رکھنا مشکل ہو جاتا ہے۔ ہر مرحلے پر قاری خود سے پوچھے گا کہ اس انٹرفیس کے دیگر نفاذ کیا ہیں اور اس کا جواب عام طور پر ہوتا ہے: صرف مذاق۔ انٹرفیس جنرلائزیشن کے لیے زیادہ پلمبنگ کوڈ کی ضرورت ہوتی ہے، خاص طور پر فیکٹریوں میں جو عام طور پر انحصار انجکشن فریم ورک پر انحصار کرتے ہیں۔ انٹرفیس جنرلائزیشن پروگرامنگ زبان کے استعمال کو بھی محدود کرتی ہے۔ عمومی پابندیاں انحصار الٹ پیٹرن (ڈی آئی پی) کو پورا کرنے کے لیے انٹرفیس کی موجودگی کے آبجیکٹ پر مبنی پروگرام میں ڈیزائن کے دیگر مضمرات ہوتے ہیں: کلاس کے تمام ممبر متغیرات انٹرفیس یا خلاصہ ہونے چاہئیں۔ تمام کنکریٹ کلاس پیکجوں کو صرف انٹرفیس یا تجریدی کلاس پیکجوں کے ذریعے مربوط ہونا چاہیے۔ کسی بھی کلاس کو ٹھوس کلاس سے اخذ نہیں کیا جانا چاہیے۔ کسی بھی طریقہ کار کو نافذ شدہ طریقہ کار پر غالب نہیں ہونا چاہیے۔ تمام متغیر فوری کاری کے لیے تخلیقی نمونے کے نفاذ کی ضرورت ہوتی ہے جیسے کہ فیکٹری کا طریقہ یا فیکٹری کا نمونہ، یا انحصار انجکشن فریم ورک کا استعمال۔ انٹرفیس کا مذاق اڑانے کی پابندیاں وراثت پر مبنی مذاق اڑانے والے ٹولز کا استعمال کرتے ہوئے بھی پابندیاں متعارف کرائی جاتی ہیں: جامد بیرونی طور پر نظر آنے والے اراکین کو منظم طریقے سے انحصار انجکشن پر انحصار کرنا چاہیے جس سے ان پر عمل درآمد کرنا بہت مشکل ہو جائے۔ تمام قابل جانچ طریقوں کو انٹرفیس کا نفاذ یا تجریدی تعریف کا اوور رائیڈ بننا چاہیے۔ مستقبل کی سمت اصول سوچنے کے طریقے ہیں۔ نمونے مسائل کو حل کرنے کے عام طریقے ہیں۔ پروگرامنگ زبان کی گمشدہ خصوصیات کے لیے کوڈنگ کے نمونے موجود ہو سکتے ہیں۔ پروگرامنگ زبانیں کم از کم دو سمتوں میں مضبوط اور زیادہ درست استعمال کے معاہدوں کو نافذ کرنے کی اجازت دینے کے لیے تیار ہوتی رہیں گی: استعمال کے حالات (پہلے، بعد اور غیر متغیر حالات) اور ریاست پر مبنی انٹرفیس کو نافذ کرنا۔ یہ ممکنہ طور پر بہت سے حالات میں انحصار الٹ پیٹرن کے مضبوط اطلاق کی حوصلہ افزائی اور ممکنہ طور پر آسان بنائے گا۔ زیادہ سے زیادہ مذاق اڑانے والے ٹولز اب جامد اور غیر ورچوئل اراکین کو تبدیل کرنے کے مسئلے کو حل کرنے کے لیے انحصار انجکشن کا استعمال کرتے ہیں۔ پروگرامنگ زبانیں شاید مذاق سے مطابقت رکھنے والا بائٹ کوڈ تیار کرنے کے لیے تیار ہوں گی۔ ایک سمت یہ ہوگی کہ غیر ورچوئل اراکین کے استعمال کو محدود کیا جائے۔ دوسرا یہ ہوگا کہ کم از کم ٹیسٹ کے حالات میں، بائٹ کوڈ تیار کیا جائے جس سے غیر وراثت پر مبنی مذاق اڑایا جا سکے۔ نفاذ ڈی آئی پی کے دو عام نفاذ اسی طرح کے منطقی فن تعمیر کا استعمال کرتے ہیں لیکن مختلف مضمرات کے ساتھ۔ ایک براہ راست نفاذ ایک لائبریری میں کلاسوں کو سروس خلاصہ کے ساتھ پالیسی کلاسوں کو پیک کرتا ہے۔ اس نفاذ میں اعلی سطح کے اجزاء اور نچلے درجے کے اجزاء کو الگ الگ پیکجوں/کتب خانوں میں تقسیم کیا جاتا ہے، جہاں اعلی سطح کے جزو کے لیے درکار رویے/خدمات کی وضاحت کرنے والے انٹرفیس کی ملکیت ہوتی ہے، اور یہ اعلی سطح کے جزو کی لائبریری کے اندر موجود ہوتے ہیں۔ نچلے درجے کے جزو کے ذریعہ اعلی درجے کے جزو کے انٹرفیس کے نفاذ کے لیے ضروری ہے کہ نچلے درجے کے جزو پیکیج کا انحصار تالیف کے لیے اعلی درجے کے جزو پر ہو، اس طرح روایتی انحصار کے تعلقات کو الٹ دیا جائے۔ شکل 1 اور 2 ایک ہی فعالیت کے ساتھ کوڈ کی وضاحت کرتے ہیں، تاہم شکل 2 میں، انحصار کو تبدیل کرنے کے لیے ایک انٹرفیس استعمال کیا گیا ہے۔ پالیسی کوڈ کے زیادہ سے زیادہ دوبارہ استعمال اور چکور انحصار کو ختم کرنے کے لیے انحصار کی سمت کا انتخاب کیا جا سکتا ہے۔ ڈی آئی پی کے اس ورژن میں، نچلی پرت کے جزو کا اعلی سطح کی تہوں میں انٹرفیس/خلاصہ پر انحصار نچلی پرت کے اجزاء کے دوبارہ استعمال کو مشکل بنا دیتا ہے۔ اس کے بجائے یہ عمل درآمد روایتی انحصار کو اوپر سے نیچے سے اس کے برعکس، نیچے سے اوپر تک "الٹ" دیتا ہے۔ ایک زیادہ لچکدار حل تجریدی اجزاء کو پیکجوں/کتب خانوں کے ایک آزاد سیٹ میں نکالتا ہے: ہر پرت کو اس کے اپنے پیکیج میں الگ کرنے سے کسی بھی پرت کے دوبارہ استعمال کی حوصلہ افزائی ہوتی ہے، جس سے مضبوطی اور نقل و حرکت فراہم ہوتی ہے۔ مثالیں نسب نامہ ماڈیول ایک نسب نامہ نظام لوگوں کے درمیان تعلقات کو ان کے درمیان براہ راست تعلقات کے گراف کے طور پر پیش کر سکتا ہے (باپ بیٹے، باپ بیٹی، ماں بیٹے، ماں بیٹی، شوہر بیوی، بیوی شوہر وغیرہ)۔ یہ بہت موثر اور قابل توسیع ہے، کیونکہ سابق شوہر یا قانونی سرپرست کو شامل کرنا آسان ہے۔ لیکن کچھ اعلی درجے کے ماڈیولز کو سسٹم کو براؤز کرنے کے لیے ایک آسان طریقہ درکار ہو سکتا ہے: کسی بھی شخص کے بچے، والدین، بہن بھائی (بشمول سوتیلے بھائی اور بہنیں یا نہیں)، دادا دادی، کزن وغیرہ ہو سکتے ہیں۔ نسب نامہ ماڈیول کے استعمال پر منحصر ہے، مشترکہ تعلقات کو الگ براہ راست خصوصیات کے طور پر پیش کرنا (گراف کو چھپانا) اعلی سطح کے ماڈیول اور نسب نامہ ماڈیول کے درمیان جوڑے کو بہت ہلکا بنا دے گا اور کسی کو براہ راست تعلقات کی اندرونی نمائندگی کو مکمل طور پر تبدیل کرنے کی اجازت دے گا۔ یہ نسب نامہ ماڈیول میں بہن بھائیوں یا چچاؤں کی درست تعریفیں شامل کرنے کی بھی اجازت دیتا ہے، اس طرح واحد ذمہ داری کے اصول کو نافذ کرتا ہے۔ آخر میں، اگر پہلا ایکسٹینسیبل جنرلائزڈ گراف اپروچ سب سے زیادہ ایکسٹینسیبل معلوم ہوتا ہے، تو نسب نامہ ماڈیول کا استعمال یہ ظاہر کر سکتا ہے کہ ایپلی کیشنز کے لیے ایک زیادہ خصوصی اور آسان تعلقات کا نفاذ کافی ہے اور ایک زیادہ موثر نظام بنانے میں مدد کرتا ہے۔ اس مثال میں، ماڈیولز کے درمیان تعامل کو خلاصہ کرنے سے نچلے درجے کے ماڈیول کا ایک آسان انٹرفیس بنتا ہے اور اس پر عمل درآمد آسان ہو سکتا ہے۔ ریموٹ فائل سرور کلائنٹ ایک ریموٹ فائل سرور (ایف ٹی پی، کلاؤڈ اسٹوریج۔) کلائنٹ کو تجریدی انٹرفیس کے ایک سیٹ کے طور پر ماڈل کیا جا سکتا ہے: کنکشن/منقطع (ایک کنکشن استقامت پرت کی ضرورت ہو سکتی ہے) فولڈر/ٹیگز تخلیق/نام تبدیل/حذف/فہرست انٹرفیس فائل تخلیق/تبدیلی/نام تبدیل/حذف/پڑھنے انٹرفیس فائل بیک وقت متبادل تلاش کرنا یا ریزولوشن فائل ہسٹری مینجمنٹ کو حذف کرنا۔ اگر مقامی اور دور دراز کی فائلیں ایک ہی تجریدی انٹرفیس پیش کرتی ہیں، تو اعلی سطحی ماڈیول جو انحصار الٹ پیٹرن کو نافذ کرتے ہیں انہیں اندھا دھند استعمال کر سکتے ہیں۔ ایپلیکیشن اپنے دستاویزات کو مقامی طور پر یا دور سے شفاف طریقے سے محفوظ کر سکے گی۔ اعلی سطحی ماڈیولز کے لیے درکار خدمت کی سطح پر غور کیا جانا چاہیے۔ ماڈیول کو تجریدی انٹرفیس کے ایک سیٹ کے طور پر ڈیزائن کرنا، اور دوسرے ماڈیولز کو اس کے مطابق ڈھالنا، بہت سے سسٹمز کے لیے ایک مشترکہ انٹرفیس فراہم کر سکتا ہے۔ ماڈل ویو کنٹرولر UI اور ایپلیکیشن لیئر پیکجوں میں بنیادی طور پر ٹھوس کلاسیں ہوتی ہیں۔ کنٹرولرز خلاصہ/انٹرفیس کی اقسام پر مشتمل ہوتے ہیں۔ UI میں ICustomerHandler کی ایک مثال ہے۔ تمام پیکجوں کو جسمانی طور پر الگ کیا جاتا ہے۔ ایپلیکیشن لیئر میں کسٹمر ہینڈلر کا ایک ٹھوس نفاذ ہے جسے پیج کلاس استعمال کرے گا۔ آئی کسٹمر ہینڈلر انٹرفیس کی مثالیں ایک فیکٹری کے ذریعہ متحرک طور پر بنائی جاتی ہیں (ممکنہ طور پر اسی کنٹرولر پیکیج میں)۔ کنکریٹ اقسام پیج اور کسٹمر ہینڈلر کا انحصار آئی کسٹمر ہینڈلر پر ہے، ایک دوسرے پر نہیں۔ چونکہ UI ایپلیکیشن لیئر یا ICustomerHandler کو لاگو کرنے والے کسی دوسرے ٹھوس پیکیج کا حوالہ نہیں دیتا ہے، اس لیے کسٹمر ہینڈلر کے ٹھوس نفاذ کو UI کلاس کو تبدیل کیے بغیر تبدیل کیا جا سکتا ہے۔ نیز، پیج کلاس انٹرفیس آئی پیج ویوئر کو لاگو کرتی ہے جسے آئی کسٹمر ہینڈلر طریقوں کے لیے ایک دلیل کے طور پر منتقل کیا جا سکتا ہے، جس سے کسٹمر ہینڈلر کے ٹھوس نفاذ کو بغیر کسی ٹھوس انحصار کے UI کے ساتھ بات چیت کرنے کی اجازت ملتی ہے۔ ایک بار پھر، دونوں انٹرفیس کے ذریعے جڑے ہوئے ہیں۔ انحصار الٹ اصول کو لاگو کرنے والے متعلقہ نمونوں کو اڈاپٹر پیٹرن کی ایک مثال کے طور پر بھی دیکھا جا سکتا ہے۔ یعنی، اعلی درجے کی کلاس اپنے اڈاپٹر انٹرفیس کی وضاحت کرتی ہے جو وہ خلاصہ ہے جس پر دیگر اعلی درجے کی کلاسیں انحصار کرتی ہیں۔ موافقت شدہ نفاذ بھی لازمی طور پر اسی اڈاپٹر انٹرفیس تجریدی پر منحصر ہے، جبکہ اسے اس کے اپنے نچلے درجے کے ماڈیول سے کوڈ کا استعمال کرکے نافذ کیا جاسکتا ہے۔ اعلی سطحی ماڈیول نچلے درجے کے ماڈیول پر منحصر نہیں ہے، کیونکہ یہ انٹرفیس پر پولیمرفک طریقوں کو لاگو کرکے اڈاپٹر انٹرفیس کے ذریعے بالواسطہ طور پر نچلے درجے کی فعالیت کا استعمال کرتا ہے جو موافقت شدہ نفاذ اور اس کے نچلے درجے کے ماڈیول کے ذریعے نافذ کیے جاتے ہیں۔ مختلف نمونوں جیسے پلگ ان، سروس لوکیٹر، یا انحصار انجکشن کو اعلی سطح کے جزو پر منتخب کردہ نچلے درجے کے جزو کے نفاذ کی رن ٹائم فراہمی کو آسان بنانے کے لیے استعمال کیا جاتا ہے۔ تاریخ انحصار الٹ اصول کو رابرٹ سی مارٹن نے پیش کیا تھا اور اسے کئی اشاعتوں میں بیان کیا گیا تھا جن میں مقالہ آبجیکٹ اورینٹڈ ڈیزائن کوالٹی میٹرکس: انحصار کا تجزیہ، مئی 1996 میں سی + + رپورٹ میں شائع ہونے والا ایک مضمون جس کا عنوان انحصار الٹ اصول تھا، اور کتابیں ایجائل سافٹ ویئر ڈویلپمنٹ، اصول، پیٹرن، اور پریکٹس، اور ایجائل اصول، پیٹرن، اور پریکٹس ان سی #شامل ہیں۔ یہ بھی دیکھیں ایڈاپٹر پیٹرن انحصار انجکشن ڈیزائن بذریعہ کنٹریکٹ انٹرفیس انوینٹر کا پیراڈوکس انورژن آف کنٹرول پلگ ان (کمپیوٹنگ) سروس لوکیٹر پیٹرن سولڈ-"سولڈ" میں "ڈی" کا مطلب انحصار الٹ اصول ہے حوالہ جات آبجیکٹ اورینٹڈ ڈیزائن کوالٹی میٹرکس: انحصار کا تجزیہ رابرٹ سی مارٹن، سی + + رپورٹ، ستمبر/اکتوبر 1995 انحصار الٹ اصول، رابرٹ سی مارٹن، سی + + رپورٹ، مئی 1996 انحصار الٹ اصول کا جائزہ لینا، ڈیریک گریر ڈی آئی پی: وائلڈ میں انحصار الٹ اصول ڈی آئی پی، بریٹ ایل شوچرٹ، مئی 2013 انحصار میں