SoC (Separation of Concerns) اس اصول کا مخفف ہے جس کے تحت سافٹ ویئر سسٹم کو ذمہ داری کے الگ تھلگ شعبوں میں تقسیم کیا جاتا ہے۔ Martin Fowler کے مطابق، توجہ کی علیحدگی قابل برقرار رکھنے والے کوڈ کا کلیدی عنصر ہے۔ اصول SoC ڈویلپرز کو ایپلیکیشن کی ایک پرت کو دوسروں کو متاثر کیے بغیر تبدیل کرنے کی اجازت دیتا ہے، جو ٹیم موبائل ڈویلپمنٹ میں خاص طور پر اہم ہے۔
اہم نکات
SoC کا مطلب Separation of Concerns ہے — «ذمہ داریوں کی علیحدگی» یا «دلچسپی کے شعبوں کی علیحدگی»۔ ڈویلپمنٹ کے سیاق و سباق میں، concern کی اصطلاح کسی بھی علیحدہ قابل فعالیت کو ظاہر کرتی ہے: یوزر انٹرفیس پیش کرنا، کلک پروسیسنگ، ڈیٹا کی توثیق، نیٹ ورک مواصلات یا ڈیٹابیس کے ساتھ کام۔ SoC اصول کوڈ کو ان شعبوں کے ارد گرد گروپ کرنے کا حکم دیتا ہے تاکہ ایک میں تبدیلی دوسروں کو متاثر نہ کرے۔
مخفف SoC تکنیکی ادب، تعمیری مباحثوں اور فریم ورک دستاویزات میں وسیع پیمانے پر استعمال ہوتا ہے۔ مثال کے طور پر، Android Architecture Components کی دستاویزات میں، ViewModel اور View کو الگ کرنے کی ترغیب کے طور پر SoC کا بار بار ذکر کیا گیا ہے۔ iOS کمیونٹی میں، یہ اصطلاح Massive View Controller کے مسئلے پر بحث کرتے وقت استعمال ہوتی ہے — جو SoC کی کمی کا براہ راست نتیجہ ہے۔
یہ سمجھنا ضروری ہے کہ SoC ایک بار کی کارروائی نہیں ہے بلکہ ایک مسلسل عمل ہے۔ جیسے جیسے ایپلیکیشن بڑھتی ہے، ذمہ داری کے نئے شعبے ابھرتے ہیں اور فن تعمیر پر نظر ثانی کرنی پڑتی ہے۔ ایک اچھا کوڈ بیس مستحکم حالت تک پہنچنے سے پہلے علیحدگی کے کئی ادوار سے گزرتا ہے جہاں ہر concern الگ تھلگ اور قابل انتظام ہوتا ہے۔
Separation of Concerns اور اس کا مخفف SoC ایک ہی اصول کو ظاہر کرتے ہیں۔ فرق صرف استعمال کے سیاق و سباق میں ہے: پورا نام رسمی دستاویزات، تعلیمی مواد اور نئے ڈویلپرز کو پہلی بار تصور سمجھاتے وقت استعمال ہوتا ہے۔ SoC تکنیکی مباحثوں، کوڈ کے جائزوں اور دستاویزات میں آسان ہے جہاں اختصار اہم ہے۔
پیشہ ورانہ ماحول میں، دونوں اصطلاحات ایک دوسرے کے بدلے استعمال کی جا سکتی ہیں۔ ایک ڈویلپر کہہ سکتا ہے «یہاں SoC کی خلاف ورزی ہوئی» یا «یہ Separation of Concerns کی خلاف ورزی کرتا ہے» — معنی نہیں بدلتا۔ تاہم، نوکری کے اشتہارات اور تعمیری ضروریات میں پورا نام زیادہ استعمال ہوتا ہے، جبکہ چیٹس اور کوڈ کے جائزوں میں مخفف استعمال ہوتا ہے۔ صنعت میں آرام سے داخلے کے لیے دونوں قسموں کا جاننا ضروری ہے۔
اصطلاحی الجھن ہے: مخفف SoC ہارڈویئر سیاق و سباق میں System-on-a-Chip (چپ پر نظام) کے لیے بھی استعمال ہوتا ہے۔ موبائل ڈویلپمنٹ میں، سیاق و سباق ہمیشہ ماحول سے واضح ہوتا ہے — اگر بحث کوڈ کے فن تعمیر کے بارے میں ہے، تو اس سے مراد Separation of Concerns ہے۔ اس مضمون میں، SoC ہمیشہ ذمہ داریوں کی علیحدگی کے اصول سے مراد ہے۔
تین پرتوں والا فن تعمیر موبائل ایپلیکیشنز میں SoC کو نافذ کرنے کا سب سے عام طریقہ ہے۔ یہ کوڈ کو Presentation (UI)، Domain (کاروباری منطق) اور Data (ڈیٹا ذرائع) میں تقسیم کرتا ہے۔ ہر پرت میں کلاسوں کی سختی سے متعین اقسام ہوتی ہیں اور انٹرفیس کے ذریعے پڑوسیوں سے الگ تھلگ ہوتی ہے۔ یہ طریقہ iOS، Android اور Flutter منصوبوں کے لیے یکساں طور پر موثر ہے۔
View اور ViewModel پریزینٹیشن پرت بناتے ہیں۔ View انٹرفیس پیش کرنے اور صارف کے واقعات کو آگے بڑھانے کے لیے ذمہ دار ہے۔ ViewModel اسکرین کی حالت رکھتا ہے اور Domain پرت سے ڈیٹا کو ڈسپلے کے لیے تیار فارمیٹ میں تبدیل کرتا ہے۔ ViewModel کے پاس Activity، Fragment یا UIViewController کا کوئی حوالہ نہیں ہے — یہ UI اور منطق کے درمیان SoC کو یقینی بناتا ہے۔
مثال کے طور پر، Android Jetpack میں، ViewModel اسکرین گھومنے سے بچ جاتا ہے جبکہ UI دوبارہ بنایا جاتا ہے۔ SoC کے بغیر، Activity میں حالت محفوظ کرنی پڑتی، زندگی کے چکر کے انتظام کو ڈیٹا کے ساتھ ملا کر۔ ViewModel اس مسئلے کو الگ تھلگ طریقے سے حل کرتا ہے، ذمہ داریوں کی علیحدگی کے اصول کا صاف نفاذ ظاہر کرتا ہے۔
Use Cases میں پلیٹ فارم سے آزاد کاروباری اصول ہوتے ہیں۔ یہ پرت Android SDK، iOS UIKit یا Flutter framework درآمد نہیں کرتی۔ Use Case Repository سے ڈیٹا وصول کرتا ہے، اس پر کاروباری منطق لاگو کرتا ہے اور نتیجہ واپس کرتا ہے۔ SoC کی بدولت، ایک Use Case کو مختلف اسکرینوں اور پلیٹ فارمز پر دوبارہ استعمال کیا جا سکتا ہے۔
ایک کلاسک مثال رجسٹریشن فارم کے لیے ValidateAndSaveUseCase ہے۔ یہ ای میل اور پاس ورڈ کی توثیق کرتا ہے، محفوظ کرنے کے لیے UserRepository کو کال کرتا ہے اور ValidationResult واپس کرتا ہے۔ نہ UI اور نہ ڈیٹابیس توثیق کے اصول جانتے ہیں — وہ ایک جگہ مرکوز ہیں، جس سے انہیں تبدیل کرنا آسان ہو جاتا ہے۔
Repository ڈیٹا کے ذرائع کو باقی ایپلیکیشن سے الگ کرتا ہے۔ ViewModel نہیں جانتا کہ ڈیٹا کہاں سے آتا ہے — REST API، GraphQL، مقامی ڈیٹابیس یا کیشے سے۔ Repository فیصلہ کرتا ہے کہ کون سا ذریعہ استعمال کرنا ہے اور اس منطق کو ایک انٹرفیس کے پیچھے چھپاتا ہے۔ یہ ڈیٹا حاصل کرنے اور ڈیٹا استعمال کرنے کے درمیان SoC ہے۔
DataSource اس سے بھی گہری علیحدگی فراہم کرتا ہے: RemoteDataSource صرف HTTP درخواستوں کے لیے ذمہ دار ہے، LocalDataSource Room، CoreData یا SharedPreferences کے ساتھ کام کرنے کے لیے ذمہ دار ہے۔ Repository کیشنگ حکمت عملی لاگو کرکے انہیں جوڑتا ہے۔ ہر DataSource کو آزادانہ طور پر تبدیل کیا جا سکتا ہے، جو سرورز یا ڈیٹابیسز کے درمیان منتقلی کے وقت اہم ہے۔
DataSource کا یہ کثیر سطحی نظام بنیادی ڈھانچے کی سطح پر SoC کو نافذ کرتا ہے: نیٹ ورک مواصلات، مقامی ذخیرہ اور کیشنگ الگ الگ concerns ہیں، ہر ایک کا اپنا منطق اور زندگی کا چکر ہے۔ HTTP کلائنٹ تبدیل کرتے وقت، صرف RemoteDataSource تبدیل ہوتا ہے، جبکہ Repository اور اوپری پرتیں اپنی جگہ رہتی ہیں، ذمہ داریوں کی علیحدگی کی عملی اہمیت کی تصدیق کرتی ہیں۔
MVP (Model-View-Presenter) موبائل ڈویلپمنٹ میں واضح طور پر SoC کو نافذ کرنے والے پہلے نمونوں میں سے ایک تھا۔ Presenter میں منطق ہوتی ہے اور ایک انٹرفیس کے ذریعے View کو کنٹرول کرتا ہے۔ View غیر فعال ہے — یہ صرف وہی دکھاتا ہے جو Presenter کہتا ہے۔ علیحدگی جانچ کو آسان بناتی ہے: Presenter ایمولیٹر کے بغیر جانچا جاتا ہے، اور View اتنا آسان رہتا ہے کہ اس میں ٹوٹنے کے لیے کچھ نہیں ہے۔
MVVM نے رد عمل بائنڈنگ شامل کی: View Observable یا StateFlow کے ذریعے ViewModel میں تبدیلیوں کو سبسکرائب کرتا ہے۔ ViewModel View کا حوالہ نہیں رکھتا، جو میموری لیک کے خطرے کو ختم کرتا ہے اور concerns کو مزید الگ کرتا ہے۔ Android میں، Jetpack ViewModel اور LiveData کی بدولت MVVM معیار بن گیا؛ iOS میں — Combine اور RxSwift کی بدولت۔
Robert Martin کی Clean Architecture SoC کو حلقوں میں بنیادی علیحدگی تک لے جاتی ہے۔ بیرونی حلقہ (فریم ورک اور ڈرائیور) اندرونی (ہستیوں) پر منحصر ہے، لیکن اس کے برعکس نہیں۔ عملی طور پر، موبائل منصوبے شاذ و نادر ہی چاروں حلقوں کو نافذ کرتے ہیں — Presentation کے ارد گرد Domain اور Data کی پرتیں کافی ہیں۔ لیکن «اندر کی طرف انحصار» کا اصول فریم ورک تبدیل کرتے وقت اہم فوائد دیتا ہے۔
// View — صرف ڈسپلے، کوئی منطق نہیں
final class LoginViewController: UIViewController {
let viewModel: LoginViewModel
func loginTapped() {
viewModel.login(emailField.text, passwordField.text)
}
}
// ViewModel — اسکرین منطق رکھتا ہے، UIKit نہیں جانتا
final class LoginViewModel {
private let loginUseCase: LoginUseCase
func login(email: String?, password: String?) {
loginUseCase.execute(email, password)
}
}
// Use Case — کاروباری منطق، پلیٹ فارم سے آزاد
final class LoginUseCase {
private let repo: AuthRepository
func execute(email: String?, password: String?) {
guard let e = email, let p = password else { return }
repo.authenticate(e, p)
}
}
مثال SoC کی تین سطحیں دکھاتی ہے: LoginViewController صرف واقعات منتقل کرتا ہے، LoginViewModel حالت کا انتظام کرتا ہے، LoginUseCase کاروباری اصول رکھتا ہے۔ ہر کلاس آزادانہ طور پر جانچی جاتی ہے، اور UI فریم ورک کو تبدیل کرنے سے Use Case متاثر نہیں ہوتا۔
Massive View Controller iOS میں SoC کی سب سے عام خلاف ورزی ہے۔ ایک کلاس جو UI کا انتظام کرتی ہے، نیٹ ورک کی درخواستوں کو پروسیس کرتی ہے، JSON کو پارس کرتی ہے اور ڈیٹا محفوظ کرتی ہے، ہر سطح پر اصول کی خلاف ورزی کرتی ہے۔ حل یہ ہے کہ ہر ذمہ داری کو ایک علیحدہ جزو میں نکالا جائے: NetworkingService، JSONParser، CoreDataStack، ViewController کو صرف View کے انتظام کے لیے چھوڑ کر۔
Android میں اسی طرح کا مسئلہ God Activity یا God Fragment ہے۔ ایک سرگرمی جو ڈیٹا لوڈ کرتی ہے، فارمز کی توثیق کرتی ہے، ڈائیلاگ دکھاتی ہے اور UI کو اپ ڈیٹ کرتی ہے۔ اس کا علاج ViewModel اور Repository متعارف کروا کر کیا جاتا ہے، جو حالت کے انتظام اور ڈیٹا کو اپنے اوپر لے لیتے ہیں۔ ViewModel اسکرین گھومنے کے دوران ڈیٹا کے نقصان سے بھی بچاتا ہے۔
تیسری خلاف ورزی پلیٹ فارم اور کاروباری کوڈ کا اختلاط ہے۔ مثال کے طور پر، براہ راست SwiftUI View یا Android Composable میں HTTP درخواست رکھنا۔ یہ کوڈ کو ناقابل منتقل اور جانچنا مشکل بنا دیتا ہے۔ صحیح طریقہ یہ ہے کہ درخواست کو Repository میں منتقل کیا جائے، جسے Use Case کے ذریعے بلایا جائے، جبکہ View صرف نتیجہ سبسکرائب کرے۔ نظام کا ہر عنصر اپنا کام حل کرتا ہے اور اپنی حدود سے باہر نہیں جاتا۔
اکثر پوچھے جانے والے سوالات
نہیں۔ SoC نظام کو ذمہ داری کے شعبوں میں تقسیم کرنے کا ایک زیادہ عمومی اصول ہے۔ SOLID آبجیکٹ اورینٹڈ ڈیزائن کے پانچ مخصوص اصولوں کا ایک مجموعہ ہے۔ SOLID کا پہلا اصول (Single Responsibility) ایک کلاس کی سطح پر SoC کی ایک خاص صورت ہے۔
تبدیلی کی ایک وجہ کا اصول (Single Responsibility) استعمال کریں۔ اگر کوئی کلاس UI، ڈیٹا فارمیٹ اور کاروباری اصولوں میں تبدیلی کی وجہ سے تبدیل ہوتی ہے — SoC کی خلاف ورزی ہوئی ہے۔ ArchTest (Android) اور StrictConcurrency (iOS) جیسے اوزار خود بخود ایسی خلاف ورزیوں کا پتہ لگانے میں مدد کرتے ہیں۔
نظریاتی طور پر، اضافی پرتیں بالواسطہ کالز شامل کرتی ہیں، لیکن عملی طور پر موبائل ایپلیکیشن کی کارکردگی پر اثر نہ ہونے کے برابر ہے۔ مرتب کرنے والا بہت سی کالوں کو ان لائن کرتا ہے، اور JIT اور AOT اصلاح اضافی بوجھ کو ختم کرتی ہے۔ کوڈ کی برقرار رکھنے کی صلاحیت تجریدوں میں کھونے سے کہیں زیادہ فائدہ دیتی ہے۔
UI سے نیٹ ورک کی درخواستوں کو نکال کر Repository میں شروع کریں۔ پھر کاروباری منطق کو Use Cases میں منتقل کریں۔ پرتوں کو جوڑنے کے لیے ڈیپنڈنسی انجیکشن استعمال کریں۔ تبدیلیاں تکراری طور پر کریں، نئے کوڈ کو ٹیسٹ سے ڈھانپیں — یہ یقینی بناتا ہے کہ ری فیکٹرنگ موجودہ فعالیت کو نہ توڑے۔
پروٹوٹائپس میں رفتار کے لیے SoC کی خلاف ورزی کی جا سکتی ہے۔ لیکن اگر پروٹوٹائپ پروڈکشن ڈویلپمنٹ میں چلا جائے تو ری فیکٹرنگ کی لاگت تیز آغاز کے فائدے سے زیادہ ہو سکتی ہے۔ بہتر یہ ہے کہ پروٹوٹائپ میں بھی کم سے کم علیحدگی (UI اور ڈیٹا) برقرار رکھی جائے تاکہ لانچ کے وقت سب کچھ شروع سے نہ لکھنا پڑے۔
خلاصہ
ہم ایک موبائل ایپلیکیشن ٹرنکی تیار کریں گے
IT Sectr 2017 سے اسٹارٹ اپس اور کاروبار کے لیے iOS اور Android ایپلیکیشنز بناتا ہے۔ ہم آپ کو مشورہ دیں گے اور بہترین حل تجویز کریں گے۔
مزید پڑھیں