ماڈیولریٹی ایک اصول ہے جس کے تحت ایپلیکیشن کو آزاد ماڈیولز سے جمع کیا جاتا ہے، ہر ایک ایک فعالیت کا ذمہ دار ہوتا ہے۔ Android Developers کے مطابق، ماڈیولز میں تقسیم متوازی کمپائلیشن کے ذریعے بلڈ کو تیز کرتی ہے اور ٹیموں کو ایپلیکیشن کے مختلف حصوں پر آزادانہ طور پر کام کرنے کی اجازت دیتی ہے۔ ماڈیولر آرکیٹیکچر درجنوں ڈویلپرز والے بڑے موبائل پروجیکٹس کے لیے معیار بن گیا ہے۔
اہم نکات
ماڈیولریٹی کوڈ کو منظم کرنے کا ایک طریقہ ہے جہاں ایک ایپلیکیشن ڈھیلے سے جڑے ماڈیولز پر مشتمل ہوتی ہے، ہر ایک عوامی انٹرفیس کے ذریعے سختی سے طے شدہ فعالیت فراہم کرتا ہے۔ یک سنگی آرکیٹیکچر کے برعکس جہاں تمام کلاسز ایک پروجیکٹ میں رہتی ہیں، ماڈیولر طریقہ کوڈ کو جسمانی طور پر آزاد بلڈ یونٹس میں تقسیم کرتا ہے۔
ماڈیولریٹی کا بنیادی مقصد پیچیدگی کا انتظام ہے۔ ایک ڈویلپر پورے کوڈبیس کو ذہن میں رکھے بغیر ایک ماڈیول پر توجہ مرکوز کرسکتا ہے۔ ہر ماڈیول کا اپنا ذمہ داری کا علاقہ ہوتا ہے اور اسے دوسروں سے آزادانہ طور پر تیار، جانچ اور تعینات کیا جاسکتا ہے۔ یہ 10+ ڈویلپرز والے پروجیکٹس میں خاص طور پر قیمتی ہے، جہاں یک سنگی پر متوازی کام بار بار انضمام کے تنازعات کا باعث بنتا ہے۔
ماڈیولریٹی کو تہہ دار آرکیٹیکچر سے الگ کرنا ضروری ہے۔ تہیں (Presentation, Domain, Data) کوڈ کو تکنیکی معیار کے مطابق تقسیم کرتی ہیں، جبکہ ماڈیولز اسے فعال معیار کے مطابق تقسیم کرتے ہیں۔ ایک “صارف پروفائل” ماڈیول اپنی اندرونی تہیں رکھ سکتا ہے۔ عملی طور پر، ماڈیولر طریقہ اور تہہ دار آرکیٹیکچر کو ملایا جاتا ہے: ہر ماڈیول کا اپنا تین تہوں پر مشتمل ڈھانچہ ہوتا ہے۔
فیچر ماڈیولز ماڈیول کی سب سے مشہور قسم ہیں۔ ہر اسکرین یا متعلقہ اسکرینوں کا گروپ اپنے علیحدہ ماڈیول میں الگ کیا جاتا ہے: Onboarding, Profile, Settings, Feed۔ ایک فیچر ماڈیول میں فیچر کے کام کرنے کے لیے درکار ہر چیز ہوتی ہے: UI، کاروباری منطق، ڈیٹا کی تہہ۔ ماڈیول کی حدود محفوظ ہوتی ہیں — دوسری فعالیتیں اس کی اندرونی کلاسز تک رسائی حاصل نہیں کرسکتیں۔
کور ماڈیولز میں مشترکہ بنیادی ڈھانچہ ہوتا ہے: نیٹ ورکنگ، ڈیٹا بیس، اینالیٹکس، ڈیزائن سسٹم۔ وہ فیچر ماڈیولز پر منحصر نہیں ہوتے، لیکن فیچر ماڈیولز ان پر منحصر ہوتے ہیں۔ یہ علیحدگی اس بات کی ضمانت دیتی ہے کہ اینالیٹکس SDK کو تبدیل کرنے سے نیٹ ورکنگ کی تہہ متاثر نہیں ہوگی، اور اس کے برعکس۔ کور ماڈیولز کوڈ کی نقل کے بغیر فعالیتوں کے درمیان دوبارہ استعمال ہوتے ہیں۔
مشترکہ ماڈیولز میں متعدد فعالیتوں کے ذریعے استعمال ہونے والا کوڈ ہوتا ہے: ڈیٹا ماڈل، افادیتیں، مستقل، حسب ضرورت ویوز۔ مشترکہ ماڈیولز کا بنیادی مسئلہ “مخلوط ماڈیول” بننے کا خطرہ ہے جہاں وقت کے ساتھ متفرق کوڈ جمع ہوتا ہے۔ قاعدہ: ایک مشترکہ ماڈیول کا واضح موضوع ہونا چاہیے، مثال کے طور پر “shared-ui” یا “shared-models”۔
Android میں، مشترکہ ماڈیولز کو اکثر lib سابقہ والی لائبریریوں میں الگ کیا جاتا ہے: lib-network, lib-database, lib-ui-components۔ iOS میں، وہی کام Workspace کے اندر اندرونی Swift Packages انجام دیتے ہیں۔ عملی طور پر، ٹیمیں بلڈ کو پیچیدہ بنانے والے ضرورت سے زیادہ انحصار نیٹ ورک سے بچنے کے لیے مشترکہ ماڈیولز کی تعداد 3-5 تک محدود کرتی ہیں۔
علیحدہ ٹیسٹ ماڈیولز پورے ٹیسٹ سوٹ کو چلائے بغیر صرف تبدیل شدہ ماڈیول کے لیے ٹیسٹ چلانے کی اجازت دیتے ہیں۔ یہ CI/CD پائپ لائن کا وقت گھنٹوں سے منٹوں تک کم کرتا ہے۔ ماڈیول سطح کی علیحدگی بلڈ کی سطح پر SoC کو یقینی بناتی ہے: نیٹ ورکنگ تہہ کا ماڈیول اپنے ٹیسٹوں میں غلطی سے UI لائبریریاں درآمد نہیں کرسکتا۔
ہر ماڈیول کا واضح طور پر طے شدہ عوامی API ہونا چاہیے۔ Android میں، یہ رسائی موڈیفائرز اور Gradle میں api بمقابلہ implementation کے ذریعے حاصل کیا جاتا ہے۔ iOS میں، public/internal رسائی موڈیفائرز اور Package.swift کے ذریعے منظم انحصار کے ذریعے۔ مرئیت کو ضروری کم سے کم تک کم کرنا ماڈیولر ڈیزائن کا ایک اہم عمل ہے۔
Gradle ماڈیولر آرکیٹیکچر کو مقامی طور پر سپورٹ کرتا ہے: ہر ماڈیول اپنی build.gradle فائل کے ساتھ ایک علیحدہ بلڈ یونٹ ہے۔ Android پروجیکٹ ایک ایپلیکیشن ماڈیول (app) اور کئی لائبریری ماڈیولز کا مجموعہ استعمال کرتے ہیں۔ لائبریری ماڈیولز کو ایپلیکیشن کے طور پر نہیں چلایا جا سکتا لیکن مخزن میں AAR کے طور پر شائع کیا جا سکتا ہے۔
Gradle کی ایک اہم خصوصیت آزاد ماڈیولز کی متوازی تعمیر ہے۔ اگر ماڈیول A، B اور C ایک دوسرے پر منحصر نہیں ہیں، تو Gradle انہیں تمام CPU کور استعمال کرتے ہوئے بیک وقت کمپائل کرتا ہے۔ 20+ ماڈیولز والے پروجیکٹس میں، یہ مکمل بلڈ کو 15 منٹ سے 3-5 منٹ تک کم کرتا ہے۔ تبدیل شدہ ماڈیول کا تدریجی بلڈ سیکنڈ لیتا ہے۔
Gradle ماڈیولز کے درمیان دو اقسام کے انحصار فراہم کرتا ہے: api (منتقلی) اور implementation (غیر منتقلی)۔ فرق ماڈیولریٹی کے لیے انتہائی اہم ہے: implementation ماڈیول صارفین سے منتقلی انحصار چھپاتا ہے۔ اگر :profile ماڈیول implementation کے ذریعے :networking استعمال کرتا ہے، تو :profile کے صارفین :networking کے بارے میں نہیں جانتے اور اس تک رسائی حاصل نہیں کر سکتے۔
// settings.gradle — ماڈیول کا اعلان
include ':app'
include ':feature:profile'
include ':feature:settings'
include ':core:network'
include ':core:database'
// build.gradle feature/profile — ماڈیول انحصار
dependencies {
implementation project(':core:network')
implementation project(':core:database')
implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.8.0'
}
کوڈ ایک ماڈیولر Android پروجیکٹ کا ڈھانچہ دکھاتا ہے۔ Settings.gradle تمام ماڈیولز کی فہرست دیتا ہے، اور ہر فیچر ماڈیول کا build.gradle صرف ان کور ماڈیولز کی وضاحت کرتا ہے جن کی اسے ضرورت ہے۔ بلڈ سسٹم خود بخود منتقلی انحصار کو حل کرتا ہے اور ماڈیولز کو صحیح ترتیب میں بناتا ہے۔
Swift Package Manager (SPM) 2019 سے iOS میں معیاری ماڈیولریٹی ٹول ہے۔ SPM ایپلیکیشن کو Swift Packages میں تقسیم کرنے کی اجازت دیتا ہے، جن میں سے ہر ایک لائبریری یا قابل عمل فائل ہو سکتا ہے۔ ایک Package Package.swift کے ذریعے ماڈیولز (targets) اور ان کے انحصار کی وضاحت کرتا ہے۔ SPM Xcode میں ضم ہے اور اضافی ٹولز کی ضرورت نہیں۔
CocoaPods تیسری پارٹی کی لائبریریوں کے لیے بنیادی انحصار مینیجر بنا ہوا ہے۔ Podfile اور Podspec ماڈیولر ڈھانچہ متعین کرتے ہیں، اور CocoaPods علیحدہ pod پروجیکٹس کے ساتھ ایک ورک اسپیس تیار کرتا ہے۔ اپنے پروجیکٹ کی ماڈیولریٹی کے لیے، ٹیمیں تیزی سے SPM کا انتخاب کر رہی ہیں کیونکہ یہ Xcode میں شامل ہے اور تنصیب کی ضرورت نہیں۔
iOS ماڈیولریٹی میں، رسائی کنٹرول اہم کردار ادا کرتا ہے: public, package, internal, fileprivate اور private۔ ایک ماڈیول صرف ان اقسام کو شائع کرتا ہے جو دوسرے ماڈیولز کے لیے قابل رسائی ہونی چاہئیں۔ اندرونی نفاذ کی تفصیلات internal اور private موڈیفائر کے پیچھے چھپی ہوتی ہیں۔ یہ ماڈیولز کے درمیان چھپے ہوئے انحصار کو روکتا ہے۔
// Package.swift — iOS پروجیکٹ کا ماڈیولر ڈھانچہ
let package = Package(
name: "MyApp",
platforms: [.iOS(SupportedPlatform.iOSVersion.v17)],
products: [
.library(name: "ProfileFeature", targets: ["ProfileFeature"]),
.library(name: "NetworkCore", targets: ["NetworkCore"]),
],
dependencies: [
.package(url: "https://github.com/Alamofire/Alamofire.git", from: "5.9.0")
],
targets: [
.target(name: "ProfileFeature", dependencies: ["NetworkCore"]),
.target(name: "NetworkCore", dependencies: ["Alamofire"]),
]
)
Package.swift دو لائبریری مصنوعات کا اعلان کرتا ہے: ProfileFeature اور NetworkCore۔ ProfileFeature NetworkCore پر منحصر ہے لیکن Alamofire کے وجود سے ناواقف ہے — یہ NetworkCore کے اندر چھپا ہوا ہے۔ اس طرح کی علیحدگی ماڈیول کی سطح پر SoC کا براہ راست اطلاق ہے: HTTP کلائنٹ میں تبدیلیوں کے لیے ProfileFeature کے دوبارہ کمپائلیشن کی ضرورت نہیں۔
ماڈیولریٹی کا بنیادی فائدہ ترقی کی رفتار ہے۔ ٹیمیں کوڈ تنازعات کے بغیر مختلف ماڈیولز پر متوازی طور پر کام کرتی ہیں۔ CI/CD پائپ لائن صرف تبدیل شدہ ماڈیولز بناتی ہے اور صرف ان کے ٹیسٹ چلاتی ہے۔ فیڈ بیک کا وقت کم ہوتا ہے اور ریلیز کی تعدد بڑھتی ہے۔ Spotify، Uber اور Airbnb نے 2-3 گنا میٹرک بہتری کے ساتھ ماڈیولر آرکیٹیکچر میں منتقلی کے کیس اسٹڈیز شائع کیے۔
دوسرا فائدہ غلطی کی علیحدگی ہے۔ Profile ماڈیول میں ایک بگ Payments ماڈیول کو متاثر نہیں کرتا اگر ان کے درمیان کوئی براہ راست انحصار نہ ہو۔ یہ خاص طور پر زیادہ خطرہ والی فعالیت (ادائیگیاں، طبی ڈیٹا) والی ایپلیکیشنز میں اہم ہے، جہاں غیر متعلقہ اسکرین میں غلطی کو اہم فعالیت کی ریلیز کو مسدود نہیں کرنا چاہیے۔
بنیادی چیلنج انحصار کا انتظام ہے۔ ناقص ڈیزائن کے ساتھ، ایک ماڈیول گراف ابھرتا ہے جہاں ایک ماڈیول کو تبدیل کرنے سے درجنوں دوسرے کی جھڑپ والی تعمیر نو ہوتی ہے۔ حل یہ ہے کہ عدم دوری کے اصول پر عمل کیا جائے: ماڈیول انحصار گراف ایک ہدایت یافتہ غیر دوری گراف (DAG) ہونا چاہیے۔ Gradle Module Graph Assert جیسے اوزار بلڈ کے وقت دوری کا پتہ لگانے میں مدد کرتے ہیں۔
دوسرا چیلنج ابتدائی سیٹ اپ وقت میں اضافہ ہے۔ ماڈیولر آرکیٹیکچر بنانے میں پروجیکٹ کے آغاز کے مرحلے میں زیادہ وقت درکار ہوتا ہے۔ 1-3 ڈویلپرز والے چھوٹے پروجیکٹ متوازی بنانے کی حقیقی ضرورت کے بغیر ماڈیول کی حدود کو برقرار رکھنے میں وقت گزار کر ماڈیولریٹی سے فائدہ نہیں اٹھا سکتے۔ حل یہ ہے کہ یک سنگی سے شروع کریں اور ٹیم کے بڑھنے کے ساتھ ماڈیولز نکالیں۔
Feature-first طریقہ ماڈیولز کو فعالیت کے مطابق گروپ کرتا ہے: ہر اسکرین یا اسکرینوں کا گروپ ایک علیحدہ ماڈیول بن جاتا ہے۔ Layer-first طریقہ کوڈ کو تکنیکی معیار کے مطابق تقسیم کرتا ہے: UI، کاروباری منطق اور ڈیٹا کے لیے علیحدہ ماڈیولز۔ عملی طور پر، زیادہ تر ٹیمیں کور ماڈیولز کے ساتھ feature-first کا انتخاب کرتی ہیں — یہ بہتر علیحدگی اور واضح پروجیکٹ نیویگیشن فراہم کرتا ہے۔
طریقوں کے درمیان انتخاب ٹیم کے سائز اور فعالیت کی پیش گوئی پر منحصر ہے۔ اگر آپ جانتے ہیں کہ پروجیکٹ میں کون سی اسکرینیں ہوں گی، تو feature-first ہر ڈویلپر کو اپنے ماڈیول کا ذمہ دار ہونے کی اجازت دیتا ہے۔ اگر فعالیت بار بار بدلتی ہے اور اسکرینوں کے درمیان اوورلیپ ہوتی ہے، تو layer-first مختلف فعالیتوں کے درمیان کوڈ کے دوبارہ استعمال میں زیادہ لچک فراہم کرتا ہے۔
اکثر پوچھے گئے سوالات
بہترین تعداد پروجیکٹ اور ٹیم کے سائز پر منحصر ہے۔ 5 افراد کی ٹیم کے لیے 6-10 ماڈیول کافی ہیں۔ 20+ ڈویلپرز کے لیے 20-40 ماڈیول۔ قاعدہ: ماڈیول اتنا چھوٹا ہونا چاہیے کہ ایک ڈویلپر اسے مکمل طور پر سمجھ سکے، اور اتنا بڑا کہ ضرورت سے زیادہ انحصار نیٹ ورک نہ بنائے۔
مناسب ماڈیولریٹی متوازی کمپائلیشن اور کیشنگ کے ذریعے بلڈ کو تیز کرتی ہے۔ لیکن تنگ انحصار والے ضرورت سے زیادہ ماڈیول بلڈ کو سست کرتے ہیں — Gradle اور Xcode گراف کو حل کرنے میں وقت صرف کرتے ہیں۔ تیز بلڈ کی کلید منتقلی انحصار کو کم سے کم کرنا اور عدم دوری کو برقرار رکھنا ہے۔
ہاں، لیکن تدریجی طور پر۔ کور ماڈیولز (نیٹ ورک، ڈیٹا بیس) نکال کر شروع کریں، پھر ایک ایک کر کے فعالیتیں نکالیں۔ پرانے یک سنگی کوڈ کے ساتھ نئے ماڈیولر کوڈ کو فعال کرنے کے لیے feature flags استعمال کریں۔ بڑی ایپلیکیشن کی مکمل منتقلی میں 3 سے 12 مہینے لگتے ہیں۔
ماڈیولز ایک ایپلیکیشن کے اندر کمپائلیشن یونٹ ہیں۔ مائیکرو سروسز علیحدہ سرورز پر چلنے والے علیحدہ عمل ہیں۔ ماڈیولز کوڈ کو تقسیم کرتے ہیں، مائیکرو سروسز رن ٹائم کو تقسیم کرتی ہیں۔ موبائل ڈویلپمنٹ میں، “microapps” کی اصطلاح اکثر ایک ہائبرڈ کے طور پر استعمال ہوتی ہے: فیچر ماڈیولز جو خود مختار ایپلیکیشنز کے طور پر چل سکتے ہیں۔
ہر ماڈیول کے اپنے یونٹ ٹیسٹ ہوتے ہیں جو آزادانہ طور پر چلتے ہیں۔ انضمام ٹیسٹ ماڈیولز کے درمیان تعامل کی تصدیق کرتے ہیں۔ UI ٹیسٹ فرضی ڈیٹا کے ساتھ فیچر ماڈیولز کا احاطہ کرتے ہیں۔ ماڈیولر آرکیٹیکچر جانچ کو آسان بناتا ہے: دوسرے ماڈیول کے انحصار کا فرضی نمونہ بنانا یک سنگی کے حصے کا فرضی نمونہ بنانے سے زیادہ آسان ہے۔
خلاصہ
ہم ایک موبائل ایپلیکیشن ٹرنکی تیار کریں گے
IT Sectr 2017 سے اسٹارٹ اپس اور کاروبار کے لیے iOS اور Android ایپلیکیشنز بناتا ہے۔ ہم آپ کو مشورہ دیں گے اور بہترین حل تجویز کریں گے۔
مزید پڑھیں