Separation of Concerns ایک اصول ہے جس کے تحت ایپلیکیشن کا ہر ماڈیول یا پرت ذمہ داری کے ایک شعبے کا ذمہ دار ہے۔ Wikipedia کے مطابق، یہ اصطلاح Edsger Dijkstra نے 1974 میں متعارف کروائی تھی، اور تب سے یہ سافٹ ویئر فن تعمیر کی بنیاد بن گئی ہے۔ ذمہ داریوں کی علیحدگی ڈیولپرز کو کوڈ کی ایک پرت کو تبدیل کرنے کی اجازت دیتی ہے بغیر دوسروں کو متاثر کیے، جو طویل سپورٹ سائیکل والے موبائل منصوبوں میں انتہائی اہم ہے۔
اہم نکات
Separation of Concerns ایک سافٹ ویئر سسٹم کو آزاد حصوں میں تقسیم کرنے کا اصول ہے، جن میں سے ہر ایک ایک کام حل کرتا ہے۔ اصطلاح concern (ذمہ داری کا شعبہ) فعالیت کے کسی بھی علیحدہ حصے کی نشاندہی کرتی ہے: اسکرین ڈسپلے، ٹیپ پروسیسنگ، ڈیٹا کی توثیق یا نیٹ ورک مواصلات۔ اصول کوڈ کو اس طرح گروپ کرنے کا حکم دیتا ہے کہ ایک شعبے میں تبدیلیوں کے لیے دوسرے شعبوں میں تبدیلیوں کی ضرورت نہ ہو۔
موبائل ڈیولپمنٹ میں، SoC کئی سطحوں پر ظاہر ہوتا ہے: ایپلیکیشن کو اسکرینوں میں تقسیم کرنے سے لے کر ایک کلاس کے اندر کوڈ کو منظم کرنے تک۔ ایک Activity یا ViewController جو بیک وقت نیٹ ورک سے ڈیٹا لوڈ کرتا ہے، JSON پارس کرتا ہے اور UI پیش کرتا ہے، Separation of Concerns کی خلاف ورزی کرتا ہے — ایسا کوڈ برقرار رکھنا، جانچنا اور بڑھانا مشکل ہے۔ متبادل یہ ہے کہ ہر ذمہ داری کو ایک علیحدہ جزو میں نکالا جائے۔
یہ اصول تجربہ کے تصور سے قریب سے جڑا ہوا ہے: ہر پرت ایک سختی سے متعین انٹرفیس فراہم کرتی ہے اور نفاذ کی تفصیلات چھپاتی ہے۔ اس کی بدولت، ایک ڈیولپر UI منطق کو دوبارہ لکھے بغیر نیٹ ورک لائبریری یا ڈیٹا بیس کو تبدیل کر سکتا ہے۔ یہ طویل مدتی منصوبوں میں خاص طور پر قیمتی ہے جہاں تقاضے اور ٹیکنالوجیاں وقت کے ساتھ بدلتی ہیں۔
Edsger Dijkstra نے پہلی بار 1974 کے اپنے مضمون «On the Role of Scientific Thought» میں Separation of Concerns کے خیال کو مرتب کیا۔ انہوں نے استدلال کیا کہ سافٹ ویئر سسٹم کی پیچیدگی کو انہیں حصوں میں تقسیم کرکے کنٹرول کیا جا سکتا ہے جن کا الگ تھلگ تجزیہ کیا جاتا ہے۔ یہ نقطہ نظر اس وقت کے یک سنگی پروگراموں کے برعکس تھا، جہاں کوڈ حساب، ان پٹ/آؤٹ پٹ اور یوزر انٹرفیس کو ملاتا تھا۔
1980 کی دہائی میں، اس خیال کو ساختہ پروگرامنگ کے حامیوں نے تیار کیا، اور پھر آبجیکٹ اورینٹڈ نقطہ نظر نے۔ Smalltalk اور C++ جیسی زبانوں نے encapsulation اور modularity کے طریقہ کار فراہم کیے جنہوں نے SoC کو ایک عملی آلہ بنا دیا۔ جدید فن تعمیر کے نمونے — MVC، MVP، MVVM اور Clean Architecture — Separation of Concerns کے اصول کے براہ راست مجسم ہیں۔
موبائل ڈیولپمنٹ کی دنیا میں، Apple نے iOS کے لیے MVC کو معیار کے طور پر فروغ دیا، جہاں Model-View-Controller ڈیٹا، ڈسپلے اور کنٹرول منطق کو الگ کرتا ہے۔ Google نے Android کے لیے ViewModel اور Repository پر مبنی فن تعمیر کے رہنما اصول تجویز کیے — ہر جزو اپنا محدود کام حل کرتا ہے۔ SoC کے بغیر، موبائل ایپلیکیشنز Massive View Controller — ہزاروں لائنوں کی کلاسیں — بن جاتی ہیں جہاں کوئی بھی تبدیلی پوری فعالیت کو توڑنے کا خطرہ رکھتی ہے۔
چار اہم پرتیں ایک عام موبائل ایپلیکیشن فن تعمیر تشکیل دیتی ہیں جو Separation of Concerns کو لاگو کرتا ہے۔ ہر پرت صرف اپنے ڈومین کی ذمہ دار ہے اور انٹرفیس کے ذریعے پڑوسیوں کے ساتھ تعامل کرتی ہے۔
View صرف ڈیٹا ڈسپلے کرنے اور صارف کے واقعات پر کارروائی کرنے کی ذمہ دار ہے۔ iOS میں یہ UIViewController اور UIView ہے، Android میں — Fragment یا Activity۔ ViewModel میں اسکرین کی حالت اور ڈیٹا کو ڈسپلے کے لیے تیار فارمیٹ میں تبدیل کرنے کی منطق ہوتی ہے۔ علیحدگی اس بات کو یقینی بناتی ہے کہ UIKit کو SwiftUI سے تبدیل کرنا یا Jetpack Compose کے ساتھ اسکرین کو دوبارہ لکھنا کاروباری منطق کو متاثر نہیں کرے گا۔
ViewModel کی جانچ کے لیے ایمولیٹر یا سمیلیٹر چلانے کی ضرورت نہیں ہے — یونٹ ٹیسٹ جو ڈیٹا کی تبدیلی اور صارف کے اقدامات پر ردعمل کی تصدیق کرتے ہیں، کافی ہیں۔ یہ Separation of Concerns کا براہ راست نتیجہ ہے: UI کاروباری اصولوں کے ساتھ نہیں ملتا، اور ہر جزو الگ تھلگ جانچا جاتا ہے۔
Use Case (یا Interactor) میں ایپلیکیشن کے کاروباری اصول شامل ہیں — حسابات، توثیق، ڈیٹا کالز کی ترتیب۔ یہ پرت UI اور پلیٹ فارم فریم ورک کے وجود کے بارے میں نہیں جانتی۔ Use Case Repository سے ڈیٹا حاصل کرتا ہے، اس پر منطق لاگو کرتا ہے اور تیار نتیجہ ViewModel کو واپس کرتا ہے۔ علیحدگی ایک Use Case کو مختلف اسکرینوں پر دوبارہ استعمال کرنے کی اجازت دیتی ہے۔
مثال کے طور پر، LoginUseCase ای میل کی درستگی چیک کرتا ہے، تصدیق کے لیے AuthRepository کو کال کرتا ہے اور نتیجہ واپس کرتا ہے۔ یہ لاگ ان اسکرین کی شکل پر منحصر نہیں ہے — SwiftUI، UIKit یا Compose۔ اگر کاروباری اصول تبدیل ہوتے ہیں، تو UI یا ڈیٹا بیس کو چھوئے بغیر ایک Use Case کو تبدیل کرنا کافی ہے۔
Repository ڈیٹا ذرائع کو تجریدی بناتا ہے: ریموٹ API، مقامی ڈیٹا بیس یا میموری کیش۔ ViewModel اور Use Case نہیں جانتے کہ ڈیٹا کہاں سے آتا ہے — Repository فیصلہ کرتا ہے کہ نیٹ ورک سے لوڈ کرنا ہے یا کیش سے۔ یہ علیحدگی کاروباری منطق یا UI کو متاثر کیے بغیر اسٹوریج کے نفاذ کو تبدیل کرنے کی اجازت دیتی ہے۔
DataSource ایک اور بھی نچلی سطح کی علیحدگی ہے: NetworkDataSource صرف HTTP درخواستوں کا ذمہ دار ہے، LocalDataSource — Room یا CoreData کے ساتھ کام کرنے کا۔ Repository مختلف DataSources کی کالز کو ایک مربوط انٹرفیس میں یکجا کرتا ہے۔ ہر DataSource کو mock یا فرضی سرورز کا استعمال کرتے ہوئے آزادانہ طور پر جانچا جاتا ہے۔
DataSource پرت کا درست نفاذ اس بات کو یقینی بناتا ہے کہ ڈیٹا بیس سکیما کو تبدیل کرنا یا REST API کو GraphQL سے بدلنا صرف ایک DataSource کو متاثر کرے گا، لیکن Repository یا اس کے صارفین کو نہیں۔ یہ انفراسٹرکچر کی سطح پر Separation of Concerns کا براہ راست نتیجہ ہے: ہر تکنیکی شعبہ الگ تھلگ اور جھرن والی تبدیلیوں کے بغیر تبدیل کیا جا سکتا ہے۔
MVVM (Model-View-ViewModel) موبائل ڈیولپمنٹ کے لیے سب سے مشہور پیٹرن ہے، جو براہ راست Separation of Concerns کو لاگو کرتا ہے۔ Model میں ڈیٹا اور کاروباری منطق ہوتی ہے، View ڈسپلے کی ذمہ دار ہے، اور ViewModel رد عمل کے طریقہ کار کے ذریعے انہیں جوڑتا ہے۔ Flutter میں، BLoC واقعات، حالتوں اور کاروباری منطق میں علیحدگی کے ساتھ اسی طرح کا کردار ادا کرتا ہے۔
Robert Martin (Uncle Bob) کی Clean Architecture SoC کو زیادہ سے زیادہ لے جاتی ہے: نظام آزاد حلقوں میں تقسیم ہوتا ہے — ہستیاں، استعمال کے معاملات، اڈیپٹر اور فریم ورک۔ اندرونی حلقے (ہستیاں) بیرونی حلقوں (فریم ورک) پر منحصر نہیں ہوتے۔ یہ ایپلیکیشن کی بنیادی منطق کو دوبارہ لکھے بغیر ڈیٹا بیس، UI فریم ورک اور یہاں تک کہ پلیٹ فارم کو تبدیل کرنے کی اجازت دیتا ہے۔
عملی طور پر، موبائل منصوبے شاذ و نادر ہی مکمل Clean Architecture کو لاگو کرتے ہیں — زیادہ تر ایپلیکیشنز کے لیے تین پرتوں والا فن تعمیر کافی ہے: UI، ڈومین اور ڈیٹا۔ ڈومین پرت میں Use Cases اور کاروباری ماڈل ہوتے ہیں اور یہ Android SDK یا iOS SDK سے مکمل طور پر الگ تھلگ ہے۔ اس طرح کی علیحدگی 20% کوشش سے 80% فائدہ دیتی ہے۔
// Data layer — صرف ڈیٹا حاصل کرنے کا ذمہ دار
class UserRepository(private val api: UserApi) {
suspend fun getUser(id: String): User = api.fetchUser(id)
}
// Domain layer — کاروباری منطق، API یا ڈیٹا بیس کے بارے میں نہیں جانتا
class GetUserNameUseCase(
private val repo: UserRepository
) {
suspend fun invoke(id: String): String {
val user = repo.getUser(id)
return "${user.firstName} ${user.lastName}"
}
}
// UI layer — صرف ڈسپلے
class UserViewModel(
private val getUserName: GetUserNameUseCase
) {
fun onUserLoaded(id: String) {
viewModelScope.launch {
_name.value = getUserName.invoke(id)
}
}
}
مندرجہ بالا کوڈ خالص علیحدگی کو ظاہر کرتا ہے: UserRepository صرف API کے ساتھ کام کرتا ہے، GetUserNameUseCase نام کی فارمیٹنگ کی کاروباری منطق پر مشتمل ہے، اور UserViewModel UI حالت کا انتظام کرتا ہے۔ ہر کلاس کے پاس تبدیل ہونے کی ایک وجہ ہے، جو Separation of Concerns کا جوہر ہے۔
SoC کا بنیادی فائدہ برقرار رکھنے کی اہلیت ہے۔ آزاد پرتوں میں تقسیم شدہ کوڈ کا تجزیہ کرنا آسان ہے: ڈیولپر صرف اس پرت کو دیکھتا ہے جہاں خرابی ہوتی ہے اور باقی سے مشغول نہیں ہوتا۔ طویل مدتی منصوبوں میں، یہ یک سنگی کوڈ کے مقابلے میں بگ تلاش کرنے اور ٹھیک کرنے کا وقت 30–50% کم کر دیتا ہے۔
دوسرا اہم فائدہ جانچ پڑتال کی اہلیت ہے۔ جب کاروباری منطق UI اور فریم ورک سے الگ تھلگ ہوتی ہے، تو یہ ایمولیٹر چلائے بغیر یونٹ ٹیسٹوں سے ڈھکی جاتی ہے۔ اعلی یونٹ ٹیسٹ کوریج والے Android اور iOS منصوبوں میں نئی خصوصیات شامل کرتے وقت نمایاں طور پر کم تنزلی ہوتی ہے۔
بنیادی حد بڑھتی ہوئی پیچیدگی ہے۔ مائیکرو پرتوں اور تجریدوں میں ضرورت سے زیادہ تقسیم اس طرف لے جاتی ہے کہ ایک سادہ بٹن شامل کرنے کے لیے ڈیولپر کو پانچ فائلیں ترمیم کرنی پڑتی ہیں۔ Separation of Concerns کے اصول کو معقول توازن کی ضرورت ہے: صرف ان شعبوں کو الگ کریں جو واقعی آزادانہ طور پر تبدیل ہوتے ہیں۔ چھوٹے منصوبوں کے لیے، اضافی تجریدوں کے بغیر UI، منطق اور ڈیٹا میں بنیادی علیحدگی کافی ہے۔
اکثر پوچھے گئے سوالات
SoC ذمہ داری کے شعبوں کے لحاظ سے علیحدگی کا اصول ہے، جبکہ ماڈیولریٹی کوڈ کو جسمانی ماڈیولز میں منظم کرنے کا ایک طریقہ ہے۔ SoC کو ایک ماڈیول کے اندر پرتوں یا کلاسز کے ذریعے لاگو کیا جا سکتا ہے، جبکہ ماڈیولریٹی کو آزاد بلڈز میں تقسیم کی ضرورت ہوتی ہے۔
SoC، SOLID اصولوں کے اوپر ایک بالائی ڈھانچہ ہے۔ واحد ذمہ داری کا اصول (S) ایک کلاس کی سطح پر SoC ہے۔ انحصار الٹنے کا اصول (D) انٹرفیس اور انحصار انجیکشن کے ذریعے پرتوں کے درمیان SoC کو لاگو کرنے میں مدد کرتا ہے۔
ہاں، لیکن معتدل حد تک۔ ایک سادہ ایپلیکیشن کے لیے، UI اور کاروباری منطق کو الگ کرنا کافی ہے۔ پرتوں کی ضرورت سے زیادہ تعداد عملی فائدے کے بغیر کوڈ کو پیچیدہ بنائے گی۔ جیسے جیسے منصوبہ بڑھتا ہے، پرتوں کی تعداد بتدریج بڑھائی جاتی ہے۔
کارکردگی پر کوئی براہ راست اثر نہیں ہے — SoC کا تعلق کوڈ کے فن تعمیر سے ہے، عملدرآمد سے نہیں۔ تاہم، پرتوں میں علیحدگی پرتوں کے درمیان اضافی کالوں کی وجہ سے بالواسطہ اوور ہیڈ شامل کر سکتی ہے۔ عملی طور پر، برقرار رکھنے کی اہلیت کے فوائد کے مقابلے میں یہ اثر نہ ہونے کے برابر ہے۔
انحصار انجیکشن (Hilt، Koin، Swinject) پرتوں کے درمیان حدود کو واضح طور پر منظم کرتا ہے۔ Detekt (Android) اور SwiftLint (iOS) میں آرکیٹیکچرل لنٹر قواعد ناقابل اجازت پرتوں سے درآمدات کو منع کرتے ہیں۔ Git ہکس چیک کر سکتے ہیں کہ کاروباری پرت UI لائبریریاں درآمد نہیں کرتی۔
خلاصہ
ہم ایک موبائل ایپلیکیشن ٹرنکی تیار کریں گے
IT Sectr 2017 سے اسٹارٹ اپس اور کاروبار کے لیے iOS اور Android ایپلیکیشنز بناتا ہے۔ ہم آپ کو مشورہ دیں گے اور بہترین حل تجویز کریں گے۔
مزید پڑھیں