OCP (Open/Closed Principle) SOLID کا دوسرا اصول ہے، جو طے کرتا ہے: سافٹ ویئر کے وجود کو توسیع کے لیے کھلا لیکن ترمیم کے لیے بند ہونا چاہیے۔ یہ اصول، برٹرینڈ میئر نے 1988 میں وضع کیا، موجودہ کوڈ کو تبدیل کیے بغیر نئی فعالیت شامل کرنے کی اجازت دیتا ہے۔ رابرٹ مارٹن کی کتاب Clean Architecture (2017) کے مطابق، کشادگی کا اصول تجرید اور کثیر شکلیت کے ذریعے نافذ کیا جاتا ہے، جو تنزلی کی غلطیوں کے خطرے کو کم کرتا ہے۔
بنیادی نکات
OCP (Open/Closed Principle) — توسیع کے لیے کشادگی اور ترمیم کے لیے بندش کا اصول۔ کلاسز، ماڈیولز اور فنکشنز کو اس طرح ڈیزائن کیا جانا چاہیے کہ ان کے سورس کوڈ کو تبدیل کیے بغیر نیا رویہ شامل کیا جا سکے۔ توسیع وراثت، ترکیب یا انٹرفیس کے نفاذ کی تبدیلی کے ذریعے حاصل کی جاتی ہے۔
برٹرینڈ میئر نے اپنی کتاب Object-Oriented Software Construction (1988) میں پہلی بار وراثت کے ذریعے OCP بیان کیا: بنیادی کلاس تبدیل نہیں ہوتی، جبکہ ذیلی کلاسز اس کے رویے کو بڑھاتی ہیں۔ OCP کی جدید تشریح، رابرٹ مارٹن کی تجویز کردہ، کثیر شکلیت اور انٹرفیس پر مبنی ہے: وراثت کے بجائے تجریدی معاہدے استعمال کیے جاتے ہیں۔
طریقوں کے درمیان فرق اہم ہے۔ وراثت بنیادی اور مشتق کلاسز کے درمیان مضبوط جوڑ پیدا کرتی ہے۔ انٹرفیس اور ترکیب لچک فراہم کرتے ہیں: کلائنٹ کوڈ کو تبدیل کیے بغیر نفاذ تبدیل کیا جا سکتا ہے۔ جدید OCP وراثت کے بارے میں نہیں، تجرید کے بارے میں ہے۔
کثیر شکلی OCP ایک معاہدہ طے کرنے کے لیے تجریدی کلاسز یا انٹرفیس استعمال کرتا ہے۔ کلائنٹ کوڈ ٹھوس نفاذ کو جانے بغیر تجرید کے ساتھ کام کرتا ہے۔ نئی فعالیت اسی انٹرفیس کو نافذ کرنے والی نئی کلاس بنا کر شامل کی جاتی ہے — موجودہ کوڈ میں ایک بھی تبدیلی کے بغیر۔ یہ نظام کو تبدیلی کے خلاف مزاحم اور توسیع کے لیے پیش قیاسی بناتا ہے۔
موبائل ڈویلپمنٹ میں، یہ طریقہ ہر جگہ موجود ہے: Strategy نمونہ ایک مشترکہ انٹرفیس کے ذریعے الگورتھم (تصویری دباؤ، کیشنگ، تصدیق) کو تبدیل کرنے کی اجازت دیتا ہے۔ نئی حکمت عملی شامل کرنے کے لیے اسے استعمال کرنے والے کوڈ کو تبدیل کرنے کی ضرورت نہیں ہے۔
OCP کو نافذ کرنا قابل تبدیلی رویے کو تجرید میں الگ کرنے سے شروع ہوتا ہے۔ اگر کوڈ میں switch تعمیر یا if-else سلسلہ کسی آبجیکٹ کی قسم چیک کر رہا ہے — یہ OCP لاگو کرنے کا اشارہ ہے۔ ہر شرطی شاخ کو توسیع کے وقت ایک نئی شاخ شامل کرنے کی ضرورت ہو سکتی ہے۔
OCP کے تحت ری فیکٹرنگ کے عمل میں تین مراحل شامل ہیں: قابل تبدیلی پہلو (جسے بڑھایا جا سکتا ہے) کی نشاندہی کریں، اسے انٹرفیس یا تجریدی کلاس میں الگ کریں، کلائنٹ کوڈ کو ٹھوس کلاس کے بجائے تجرید کے ساتھ کام کرنے کے لیے دوبارہ لکھیں۔ اس کے بعد، نئی فعالیت کلائنٹ کو تبدیل کیے بغیر شامل کی جاتی ہے۔
ایک اہم وضاحت: ترمیم کے لیے بندش مطلق نہیں ہے۔ اگر ضرورت میں تبدیلی خود تجرید یا معاہدے کو متاثر کرتی ہے — تو تبدیلی ناگزیر ہے۔ OCP معاہدوں میں نہیں، نفاذ میں تبدیلیوں سے بچاتا ہے۔ اچھا ڈیزائن فرض کرتا ہے کہ معاہدے مستحکم ہیں اور نفاذ قابل تبدیلی ہیں۔
کسی فن تعمیر کی OCP مطابقت کا جائزہ لیتے وقت، توسیع پوائنٹس کو دیکھنا مفید ہے۔ ہر وہ نقطہ جہاں ڈویلپر نئی قسم کے لیے if-else یا switch شامل کرتا ہے — تجرید کے لیے امیدوار ہے۔ OCP کے مطابق ڈیزائن کردہ نظام میں پیش قیاسی توسیع پوائنٹس ہوتے ہیں: دستاویزات کے ساتھ انٹرفیس جو کہتا ہے "نیا قسم شامل کرنے کے لیے یہ انٹرفیس نافذ کریں"۔ Android میں، ViewModelProvider.Factory کے ساتھ Factory نمونہ ایک واضح مثال ہے — نیا ViewModel قسم شامل کرنے کے لیے موجودہ فیکٹریوں کو تبدیل کرنے کی ضرورت نہیں ہے۔
سب سے مؤثر نمونے موبائل ڈویلپمنٹ میں OCP پر عمل کرنے کے لیے Strategy، Template Method، Decorator اور Factory شامل ہیں۔ ہر ایک مختلف آبجیکٹ اورینٹڈ ڈیزائن میکانزم کے ذریعے موجودہ کوڈ میں ترمیم کیے بغیر رویے کو بڑھانے کا مسئلہ حل کرتا ہے۔
Strategy ایک مشترکہ انٹرفیس کے ذریعے فوری طور پر الگورتھم تبدیل کرنے کی اجازت دیتا ہے۔ iOS ڈویلپمنٹ میں، حکمت عملیاں اینیمیشن اور فارم کی تصدیق کے لیے استعمال ہوتی ہیں۔ Template Method بنیادی کلاس میں الگورتھم کا ڈھانچہ طے کرتا ہے، اور ذیلی کلاسز مراحل کو اوور رائڈ کرتی ہیں — مشترکہ ڈھانچہ لیکن مختلف مواد والی اسکرینوں کے لیے موزوں۔
Decorator کسی آبجیکٹ کی کلاس کو تبدیل کیے بغیر متحرک طور پر رویہ شامل کرتا ہے۔ Android میں، Decorator کو کیشنگ یا لاگنگ پرت کے ساتھ Repository لپیٹنے کے لیے استعمال کیا جاتا ہے۔ Factory Method ایک انٹرفیس کے ذریعے آبجیکٹ بناتا ہے، جس سے ذیلی کلاسز فیصلہ کر سکتی ہیں کہ کس کلاس کو مثال بنانا ہے — OCP مطابق انحصار تخلیق کی بنیاد۔
نمونے کا انتخاب بڑھائے جانے والے رویے کے استحکام پر منحصر ہے۔ Strategy بہترین ہے جب الگورتھم مکمل طور پر تبدیل کیے جاتے ہیں۔ Template Method — جب ڈھانچہ مقرر ہے لیکن مراحل متغیر ہیں۔ Decorator — جب توسیع کلائنٹ کے لیے شفاف ہونی چاہیے۔ Android اور iOS میں زیادہ تر منظرناموں کے لیے، Strategy + انحصار انجیکشن کافی ہے۔
ان نمونوں کو OCP کے بغیر لاگو کرنا تکنیکی طور پر ممکن ہے لیکن معنی کھو دیتا ہے۔ یہ OCP ہی جواز پیش کرتا ہے کہ ہم تجرید کی اضافی سطح کیوں متعارف کراتے ہیں: تاکہ نظام موجودہ کوڈ کو دوبارہ لکھے بغیر بڑھ سکے۔
ادائیگی کی پروسیسنگ کے ساتھ ایک Android مثال پر غور کریں۔ OCP کے بغیر، ہر نئے ادائیگی کے نظام کے لیے ہینڈلر کلاس میں تبدیلی کی ضرورت ہوتی ہے۔ OCP کے ساتھ، موجودہ کوڈ میں ترمیم کیے بغیر ایک نیا انٹرفیس نفاذ شامل کیا جاتا ہے۔
// OCP خلاف ورزی: نیا نظام شامل کرتے وقت switch میں تبدیلی درکار ہے
class BadPaymentProcessor {
fun process(type: String) {
when (type) {
"card" -> // کارڈ پروسیسنگ
"paypal" -> // PayPal پروسیسنگ
}
}
}
// OCP مطابق ڈیزائن
interface PaymentMethod {
fun pay(amount: Double)
}
class CardPayment : PaymentMethod {
override fun pay(amount: Double) { }
}
class PayPalPayment : PaymentMethod {
override fun pay(amount: Double) { }
}
// نیا نظام — نئی کلاس، موجودہ کوڈ کو تبدیل کیے بغیر
class ApplePayPayment : PaymentMethod {
override fun pay(amount: Double) { }
}
ٹیکسٹ فیلڈ کی تصدیق کے ساتھ ایک iOS مثال Swift پروٹوکول کے ذریعے اسی منطق کو ظاہر کرتی ہے:
// OCP مطابق تصدیق
protocol ValidationRule {
func validate(_ input: String) -> Bool
}
struct EmailRule: ValidationRule {
func validate(_ input: String) -> Bool {
return input.contains("@")
}
}
struct PhoneRule: ValidationRule {
func validate(_ input: String) -> Bool {
return input.count == 11
}
}
// نیا اصول شامل کرنے کے لیے توثیق کنندہ کوڈ تبدیل کرنے کی ضرورت نہیں
struct PasswordRule: ValidationRule {
func validate(_ input: String) -> Bool {
return input.count >= 8
}
}
ان مثالوں میں OCP کا بنیادی فائدہ: ApplePay یا PasswordRule شامل کرنے کے لیے موجودہ کلاسز میں ترمیم کی ضرورت نہیں ہے۔ کوڈ افقی طور پر پھیلتا ہے — نئی فائلوں کے ذریعے، پرانی فائلوں کو تبدیل کرکے نہیں۔ یہ تنزلی کے خطرے کو کم کرتا ہے اور نئی فعالیت کے نفاذ کو تیز کرتا ہے۔
سب سے عام خلاف ورزی آبجیکٹ کی قسم پر مبنی switch یا when تعمیر ہے۔ ہر بار جب نیا قسم شامل کیا جاتا ہے، کوڈ میں وہ تمام switch ڈھونڈ کر نئی شاخ شامل کرنی پڑتی ہے۔ چھوٹا ہوا switch ایک رن ٹائم بگ ہے جو کمپائل وقت پر پکڑنا مشکل ہے۔
موبائل ڈویلپمنٹ میں، OCP کی خلاف ورزی بڑی enum کلاسز استعمال کرتے وقت ہوتی ہے جن میں enum قدر پر منحصر طریقے ہوتے ہیں۔ نیا enum عنصر شامل کرنے کے لیے پورے پروجیکٹ میں ہر switch کو تبدیل کرنا پڑتا ہے۔ متبادل — انٹرفیس کے ذریعے کثیر شکلیت، جہاں ہر قسم اپنا رویہ نافذ کرتی ہے۔
ایک اور عام خلاف ورزی God Adapter ہے: RecyclerView.Adapter (Android) یا UITableViewDataSource (iOS) جو if-else کے ذریعے مختلف سیل اقسام کو سنبھالتا ہے۔ ہر نئی سیل قسم کے لیے اڈاپٹر کو بڑھانے کی ضرورت ہوتی ہے۔ حل — ایک مشترکہ bind طریقہ کے ساتھ کثیر شکلی ViewHolder، جہاں ہر سیل قسم اپنی پیشکش کے لیے ذمہ دار ہے۔
احتیاطی تدابیر میں شامل ہیں: کثیر شکلیت کے حق میں قسم پر مبنی switch سے گریز، انٹرفیس کے ذریعے انحصار انجیکٹ کرنا اور ترتیب کے مطابق آبجیکٹ بنانے کے لیے Factory نمونہ استعمال کرنا۔ "قسم کے مطابق سوئچ" کے لیے کوڈ کا تجزیہ OCP پر مبنی ٹیموں میں کوڈ کا جائزہ لینے کا لازمی حصہ ہے۔
موجودہ OCP خلاف ورزی کی ری فیکٹرنگ Replace Conditional with Polymorphism کے ذریعے کی جاتی ہے: ہر شرطی شاخ ایک مشترکہ انٹرفیس نافذ کرنے والی علیحدہ کلاس بن جاتی ہے۔ کلائنٹ کوڈ انٹرفیس کے ساتھ کام کرنے کے لیے دوبارہ لکھا جاتا ہے، اور ٹھوس نفاذ فیکٹری یا DI کنٹینر کے ذریعے فراہم کیا جاتا ہے۔
یہ سمجھنا ضروری ہے کہ OCP اور کثیر شکلیت تمام توسیع مسائل حل نہیں کرتے۔ اگر فن تعمیر غلط چنا گیا ہے، تو نئی فعالیت شامل کرنے کے لیے نہ صرف نفاذ بلکہ معاہدے بھی تبدیل کرنے ہوں گے۔ اچھا فن تعمیر توسیع کی سمتوں کی پیش گوئی کرتا ہے اور تجریدات کو بالکل انہی مقامات پر رکھتا ہے۔ OCP میں سرمایہ کاری اتنی ہی زیادہ منافع بخش ہوتی ہے جتنا پراجیکٹ زیادہ دیر چلتا ہے اور جتنی بار مخصوص ماڈیولز کی ضروریات تبدیل ہوتی ہیں۔
اکثر پوچھے گئے سوالات
نہیں۔ OCP اسی تجرید سے متعلق نئی فعالیت شامل کرتے وقت موجودہ کوڈ کو تبدیل کرنے سے منع کرتا ہے۔ معاہدہ تبدیل کرنا، بگ ٹھیک کرنا اور ری فیکٹرنگ OCP کی خلاف ورزی نہیں ہے — اصول توسیع کے دوران جھڑکتی تبدیلیوں سے بچاتا ہے۔
Strategy OCP کا براہ راست نفاذ ہے۔ حکمت عملی انٹرفیس معاہدہ طے کرتا ہے، کلائنٹ تجرید پر منحصر ہے، اور ٹھوس حکمت عملیاں متغیر رویہ نافذ کرتی ہیں۔ نئی حکمت عملی شامل کرنے کے لیے کلائنٹ کو تبدیل کرنے کی ضرورت نہیں — یہ ترمیم کے لیے بندش کے ساتھ توسیع کے لیے کشادگی ہے۔
ہاں، وراثت اور Template Method کے ذریعے: بنیادی کلاس الگورتھم کا ڈھانچہ طے کرتی ہے، ذیلی کلاسز مراحل کو اوور رائڈ کرتی ہیں۔ تاہم، وراثت مضبوط جوڑ پیدا کرتی ہے اور انٹرفیس سے کم لچکدار ہے۔ جدید ڈویلپمنٹ میں، انٹرفیس اور ترکیب OCP کو نافذ کرنے کا ترجیحی طریقہ سمجھا جاتا ہے۔
OCP مطابق کوڈ ٹیسٹنگ کو آسان بناتا ہے: ہر انٹرفیس نفاذ الگ تھلگ ٹیسٹ کیا جاتا ہے۔ کلائنٹ کوڈ فرضی نفاذ کے ساتھ ٹیسٹ کیا جاتا ہے، جو مخصوص رویے سے منسلک ہوئے بغیر منطق کی تصدیق کرنے دیتا ہے۔ نظام کو بڑھانے کے لیے موجودہ ٹیسٹ دوبارہ لکھنے کی ضرورت نہیں ہے۔
نہیں۔ OCP اس وقت جائز ہے جب فعالی توسیع پیش قیاسی ہو۔ مستحکم کوڈ کے لیے جسے بڑھانے کا منصوبہ نہیں ہے، اضافی تجرید ضرورت سے زیادہ ہے۔ YAGNI (You Ain't Gonna Need It) OCP کے لیے ایک اچھا توازن ہے: تجرید اس وقت متعارف کرایا جاتا ہے جب رویے کا دوسرا ورائینٹ ظاہر ہوتا ہے، پہلے سے نہیں۔
خلاصہ
ہم ایک موبائل ایپلیکیشن ٹرنکی تیار کریں گے
IT Sectr 2017 سے اسٹارٹ اپس اور کاروبار کے لیے iOS اور Android ایپلیکیشنز بناتا ہے۔ ہم آپ کو مشورہ دیں گے اور بہترین حل تجویز کریں گے۔
مزید پڑھیں