Facade ایک ساختی ڈیزائن پیٹرن ہے جو کلاسز کے پیچیدہ ذیلی نظام کے لیے ایک آسان انٹرفیس فراہم کرتا ہے۔ موبائل ڈویلپمنٹ میں، Facade اکثر Service Layer یا UseCase کے طور پر نافذ کیا جاتا ہے، جو نیٹ ورک، ڈیٹا بیس اور تجزیات کے ساتھ تعامل کو چھپاتا ہے۔ Martin Fowler (Patterns of Enterprise Application Architecture, 2003) کے مطابق، Facade سروس لیئر کو منظم کرنے کے لیے کلیدی پیٹرن میں سے ایک ہے۔
اہم نکات
Facade ایک ساختی پیٹرن ہے جو ذیلی نظام کے انٹرفیس کے گروپ کے لیے ایک متحد انٹرفیس فراہم کرتا ہے۔ یہ ایک اعلیٰ سطح کا انٹرفیس متعین کرتا ہے جو ذیلی نظام کے استعمال کو آسان بناتا ہے۔ Facade نئی فعالیت نہیں جوڑتا — یہ موجودہ اجزاء کو ترتیب دیتا ہے، ان کے تعامل کی پیچیدگی کو کلائنٹ سے چھپاتا ہے۔
// پیچیدہ ذیلی نظام
class AuthApi {
suspend fun login(email: String, pass: String): TokenResponse
}
class UserDao {
suspend fun saveUser(user: UserEntity)
suspend fun getUser(id: Long): UserEntity?
}
class AnalyticsTracker {
fun track(event: String, params: Map )
}
// Facade — UI کے لیے ایک سادہ انٹرفیس
class AuthService(
private val api: AuthApi,
private val dao: UserDao,
private val analytics: AnalyticsTracker
) {
suspend fun loginUser(email: String, password: String): Result {
return runCatching {
val token = api.login(email, password)
val user = User(token.userId, email, token.accessToken)
dao.saveUser(user.toEntity())
analytics.track("login_success", mapOf("method" to "email"))
user
}
}
}AuthService ایک Facade ہے جو AuthApi، UserDao اور AnalyticsTracker کو ViewModel سے چھپاتا ہے۔ UI API، ڈیٹا بیس اور تجزیات کو تین الگ الگ درخواستیں بھیجنے کے بجائے loginUser(email, password) کو کال کرتا ہے۔ اس سے انحصار کم ہوتا ہے: اگر کل AuthApi FirebaseAuth بن جائے یا UserDao Room میں منتقل ہو جائے، تو صرف Facade بدلتا ہے، UI نہیں۔
Service Layer موبائل ایپلیکیشنز میں Facade کا ایک عام نفاذ ہے۔ یہ کاروباری منطق اور تہوں کے درمیان ہم آہنگی کو سمیٹتا ہے۔ Android میں، Service Layer اکثر UseCase (Clean Architecture) کے ذریعے نافذ کیا جاتا ہے، اور iOS میں Manager یا Service پروٹوکولز کے ذریعے۔
| جزو | ذیلی نظام میں کردار | Facade کیا چھپاتا ہے |
|---|---|---|
| AuthApi | سرور کو نیٹ ورک درخواست | درخواست کی شکل، endpoint، HTTP غلطیوں کی ہینڈلنگ |
| UserDao | ٹوکن کا مقامی ذخیرہ | ڈیٹا بیس سکیما، SQL کوزیئرس، منتقلیاں |
| AnalyticsTracker | تجزیاتی واقعات کی بھیجیں | Firebase/AppMetrica SDK، واقعات کی شکل |
| NetworkMonitor | نیٹ ورک کی دستیابی کی جانچ | ConnectivityManager، BroadcastReceiver |
AuthService چاروں اجزاء کو یکجا کرتا ہے۔ ViewModel ایک ہی طریقہ کال کرتا ہے، بغیر یہ جانے کہ پس پردہ نیٹ ورک درخواست، ڈیٹا بیس تحریر، ٹریکنگ اور نیٹ ورک جانچ ہو رہی ہے۔ جانچ کے وقت، AuthService کو mock سے بدلا جا سکتا ہے، حقیقی اجزاء کے ساتھ انضمام کے بغیر پوری تصدیقی منطق کی توثیق کرتے ہوئے۔
Facade، Adapter اور Mediator ساختی پیٹرن ہیں، لیکن مختلف مسائل حل کرتے ہیں۔ انہیں اکثر الجھایا جاتا ہے، کیونکہ تینوں ایک درمیانی شے متعارف کراتے ہیں۔ موبائل ایپلیکیشن کی مثال پر فرق کا تجزیہ کرتے ہیں۔
| پہلو | Facade | Adapter | Mediator |
|---|---|---|---|
| مقصد | ذیلی نظام کے انٹرفیس کو آسان بنانا | ایک انٹرفیس کو تبدیل کرنا | اجزاء کے درمیان انحصار کم کرنا |
| سمت | ایک انٹرفیس → ذیلی نظام | کلائنٹ → Adaptee | N اجزاء ↔ Mediator |
| انٹرفیس کی تبدیلی | نیا، آسان بناتا ہے | موجودہ کو تبدیل کرتا ہے | تبدیل نہیں کرتا، ہم آہنگ کرتا ہے |
| کیا ذیلی نظام پیٹرن کو جانتا ہے؟ | نہیں | نہیں | ہاں، Mediator کے ذریعے بات چیت کرتا ہے |
| موبائل ڈویلپمنٹ میں مثال | UseCase / Service Layer | RecyclerView.Adapter | iOS میں Coordinator |
Facade ذیلی نظام کو نہیں چھپاتا — کلائنٹ ضرورت پڑنے پر AuthApi تک براہ راست رسائی حاصل کر سکتا ہے۔ Adapter لازمی طور پر Adaptee کا انٹرفیس تبدیل کرتا ہے۔ Mediator بہت سی اشیاء کے درمیان پیچیدہ تعاملات کو ہم آہنگ کرتا ہے، جو ایک دوسرے کے بارے میں نہیں جانتیں۔
Facade کا نفاذ Kotlin میں Android کے لیے Clean Architecture کے ساتھ ہر کاروباری منظرنامے کے لیے داخلی نقطہ کے طور پر UseCase استعمال کرتا ہے۔ UseCase ایک Facade ہے جو ذخیرہ، مapper اور دیگر انحصار کو UI تہہ سے چھپاتا ہے۔
// Repository بھی ایک Facade ہے، لیکن نچلی سطح پر
class UserRepositoryImpl(
private val local: UserLocalDataSource,
private val remote: UserRemoteDataSource,
private val mapper: UserMapper
) : UserRepository {
override suspend fun getUserProfile(id: String): UserProfile {
val cached = local.getUser(id)
if (cached != null && !cached.isStale) {
return mapper.toProfile(cached)
}
val dto = remote.fetchUser(id)
val entity = mapper.toEntity(dto)
local.saveUser(entity)
return mapper.toProfile(entity)
}
}
// UseCase — کاروباری منظرنامے کے لیے Facade
class LoadUserProfileUseCase(
private val repo: UserRepository,
private val analytics: AnalyticsTracker
) {
suspend operator fun invoke(userId: String): Result {
return runCatching {
val profile = repo.getUserProfile(userId)
analytics.track("profile_loaded", mapOf("user_id" to userId))
profile
}
}
}LoadUserProfileUseCase پروفائل لوڈنگ کے منظرنامے کے لیے ایک Facade ہے۔ یہ کیشنگ منطق (local → remote)، DTO → Entity → Profile کی نقش نگاری اور تجزیاتی ٹریکنگ چھپاتا ہے۔ ViewModel invoke(userId) کال کرتا ہے اور تیار UserProfile یا ایک غلطی حاصل کرتا ہے۔ UseCase کو ذخیرہ کو mock شے سے بدل کر الگ تھلگ جانچا جا سکتا ہے۔
iOS میں Facade اکثر Manager یا Service کے طور پر نافذ کیا جاتا ہے۔ Android کے برعکس، iOS Facade کے انٹرفیس کی وضاحت کے لیے پروٹوکولز استعمال کرتا ہے، جس سے ٹیسٹوں میں نفاذات کو آسانی سے تبدیل کیا جا سکتا ہے۔ میڈیا کے ساتھ کام کرنے کے لیے Facade دیکھتے ہیں — لوڈنگ، کیشنگ اور ڈسپلے۔
protocol MediaServiceProtocol {
func loadImage(from url: URL) async -> Result<UIImage, Error>
}
final class MediaService: MediaServiceProtocol {
private let cache: ImageCache
private let downloader: ImageDownloader
private let decoder: ImageDecoder
func loadImage(from url: URL) async -> Result<UIImage, Error> {
// 1. کیش چیک کریں
if let cached = cache.image(for: url) {
return .success(cached)
}
// 2. ڈیٹا لوڈ کریں
let result = await downloader.download(from: url)
guard case let .success(data) = result else {
return .failure(MediaError.downloadFailed)
}
// 3. ڈی کوڈ کریں
guard let image = decoder.decode(data) else {
return .failure(MediaError.decodeFailed)
}
// 4. کیش میں محفوظ کریں
cache.setImage(image, for: url)
return .success(image)
}
}MediaService تین مراحل کے عمل کو سمیٹتا ہے: کیش → لوڈ → ڈی کوڈ۔ UI ImageCache، URLSession اور ImageDecoder کے انتظام کے بجائے ایک ہی طریقہ loadImage(from:) کال کرتا ہے۔ جانچ کے وقت، MediaServiceProtocol کو حقیقی لوڈنگ کے بغیر پہلے سے طے شدہ تصاویر واپس کرنے والے mock سے بدلا جا سکتا ہے۔
غلطیاں Facade کے ڈیزائن میں اس کے فوائد کو ختم کر دیتی ہیں: آسان بنانے کے بجائے آپ کو God Object ملتا ہے، جس پر پورا نظام منحصر ہوتا ہے۔ تین اہم مسائل کا تجزیہ کرتے ہیں۔
جب ایک ہی Facade میں تصدیق، پروفائل لوڈنگ، پیغام بھیجنے اور مطابقت پذیری کے طریقے ہوں — یہ ایک God Object ہے۔ علامت: ایک کلاس میں 15+ عوامی طریقے۔ حل: اسے ذمہ داری کے شعبوں کے مطابق کئی ماہر Facade میں تقسیم کریں — AuthService، ProfileService، MessagingService۔
اگر Facade ذیلی نظام کے لیے مخصوص اقسام واپس کرتا ہے (مثال کے طور پر، FirebaseUser یا RealmObject)، تو کلائنٹ پھر بھی ایک مخصوص نفاذ سے جڑا رہتا ہے۔ حل: Facade کو صرف اپنی اقسام (data class / struct) واپس کرنی چاہئیں، کلائنٹ کو ذیلی نظام کی تفصیلات سے مکمل طور پر الگ کرتے ہوئے۔
جب Facade ذیلی نظام تک براہ راست رسائی منع کرتا ہے، تو یہ رکاوٹ بن جاتا ہے۔ بعض اوقات کلائنٹ کو ذیلی نظام کے کسی مخصوص طریقے کی ضرورت ہوتی ہے، اور اسے Facade سے گزارنا ضرورت سے زیادہ ہے۔ Facade کو سخت گیٹ کیپر نہیں ہونا چاہیے: یہ ایک آسان انٹرفیس فراہم کرتا ہے، لیکن اجزاء تک براہ راست رسائی کو مسدود نہیں کرتا۔
اکثر پوچھے جانے والے سوالات
Facade ذیلی نظام کے لیے ایک آسان انٹرفیس فراہم کرتا ہے، اکثر طریقوں کا نیا سیٹ بناتا ہے۔ Proxy اصل شے کا وہی انٹرفیس برقرار رکھتا ہے، لیکن رسائی کا کنٹرول یا سست لوڈنگ جوڑتا ہے۔ Facade آسان بنانے کے لیے ہے، Proxy کنٹرول کے لیے۔
Service Layer ایپلیکیشن آرکیٹیکچر کی سطح پر Facade پیٹرن کا ایک نفاذ ہے۔ یہ UI اور کاروباری منطق کے درمیان حد متعین کرتا ہے، خدمات کے نفاذ کی تفصیلات چھپاتا ہے۔ Android میں، Service Layer اکثر UseCase کے ذریعے نافذ کیا جاتا ہے؛ iOS میں — Manager یا Service پروٹوکولز کے ذریعے۔
God Facade اس وقت پیدا ہوتا ہے جب ایک کلاس متعدد غیر متعلقہ ذیلی نظاموں کی ذمہ داری لے لیتی ہے۔ علامات: 15+ عوامی طریقے، مختلف شعبوں کے طریقے (تصدیق + ادائیگیاں + اطلاعیں)، ایسی کلاس جسے جانچنا مشکل ہو (10+ انحصار)۔ حل: ڈومین Facade میں تقسیم کریں۔
1-2 اسکرینوں والی ایپلیکیشن میں Facade غیر ضروری ہے — API اور ڈیٹا بیس کو UI سے براہ راست کال کرنا آسان اور واضح ہے۔ Facade فائدہ مند ہوتا ہے 5+ اسکرینوں اور 3+ ذیلی نظاموں پر۔ چھوٹے اور درمیانے پروجیکٹس میں، اضافی UseCase لپیٹ کے بغیر واحد Facade تہہ کے طور پر ایک Repository کافی ہے۔
Facade جانچ کو آسان بناتا ہے، کیونکہ یہ پورے ذیلی نظام کو ایک ہی mock شے سے بدل دیتا ہے۔ تین اجزاء (نیٹ ورک + ڈیٹا بیس + تجزیات) کو mock کرنے کے بجائے ایک Facade کو mock کرنا کافی ہے۔ Swift میں اس کے لیے پروٹوکولز استعمال ہوتے ہیں، Kotlin میں — interface۔ Facade انضمامی ٹیسٹوں کے لیے بھی موزوں ہے، جہاں اجزاء کی ترتیب کی توثیق کی جاتی ہے۔
خلاصہ
ہم ایک موبائل ایپلیکیشن ٹرنکی تیار کریں گے
IT Sectr 2017 سے اسٹارٹ اپس اور کاروبار کے لیے iOS اور Android ایپلیکیشنز بناتا ہے۔ ہم آپ کو مشورہ دیں گے اور بہترین حل تجویز کریں گے۔
مزید پڑھیں