SOLID: اصول، OOP کے 5 قواعد اور ڈیولپمنٹ میں اطلاق

مصنف: IT Sectr اشاعت: 2026-05-11 مطالعے کا وقت: 10 منٹ

SOLID — آبجیکٹ اورینٹڈ پروگرامنگ کے پانچ اصول جو Robert C. Martin (Uncle Bob) نے 2000 کی دہائی کے اوائل میں وضع کیے تھے۔ DigitalOcean، 2024 کے مطابق، SOLID کا مطلب ہے Single Responsibility، Open-Closed، Liskov Substitution، Interface Segregation اور Dependency Inversion۔ یہ اصول Clean Architecture کی بنیاد بناتے ہیں اور Android ڈیولپمنٹ (MVP، MVVM، Clean Architecture) اور iOS (VIPER، TCA) میں لاگو ہوتے ہیں۔

اہم نکات

  • SOLID — پانچ OOP اصولوں کا مخفف: SRP، OCP، LSP، ISP، DIP، جو Robert C. Martin نے لچکدار اور برقرار رکھنے کے قابل کوڈ بنانے کے لیے وضع کیے تھے۔
  • SRP (Single Responsibility) — ہر کلاس میں تبدیلی کی ایک وجہ ہوتی ہے، فی ماڈیول ایک ذمہ داری۔
  • OCP (Open-Closed) — کلاسیں توسیع کے لیے کھلی ہوتی ہیں لیکن ترمیم کے لیے بند، وراثت اور پولیمورفزم کے ذریعے لاگو ہوتا ہے۔
  • LSP (Liskov Substitution) — ذیلی کلاسوں کی اشیاء کو پروگرام کی درستگی کو تبدیل کیے بغیر بنیادی کلاس کی اشیاء کی جگہ لینے کے قابل ہونا چاہیے۔
  • ISP (Interface Segregation) — کلائنٹس کو ان انٹرفیسز پر انحصار نہیں کرنا چاہیے جو وہ استعمال نہیں کرتے، انٹرفیسز تنگ اور مخصوص ہونے چاہئیں۔
  • DIP (Dependency Inversion) — اعلیٰ سطح کے ماڈیولز ادنیٰ سطح کے ماڈیولز پر انحصار نہیں کرتے، دونوں تجریدات پر انحصار کرتے ہیں۔

SOLID کیا ہے؟ پانچ اصولوں کا جائزہ

SOLID — ایک حفظی مخفف جو آبجیکٹ اورینٹڈ ڈیزائن کے پانچ اصولوں کی نمائندگی کرتا ہے۔ یہ اصطلاح Robert C. Martin نے مضمون «Design Principles and Design Patterns» (2000) میں متعارف کروائی اور بعد میں کتاب «Agile Software Development: Principles, Patterns, and Practices» (2002) میں مقبول ہوئی۔ SOLID کوئی فریم ورک یا لائبریری نہیں ہے — یہ ان طریقوں کا ایک مجموعہ ہے جو کوڈ کو کم منحصر، زیادہ قابل آزمائش اور تبدیل کرنے میں آسان بناتے ہیں۔

Clean Coder Blog، 2014 کے مطابق، ہر SOLID اصول ایک مخصوص ڈیزائن کے مسئلے کو حل کرتا ہے: SRP God کلاسوں سے لڑتا ہے، OCP جھڑی ہوئی تبدیلیوں کو روکتا ہے، LSP غلط وراثت سے بچاتا ہے، ISP بڑے انٹرفیسز سے بچتا ہے اور DIP مضبوط انحصار کو کم کرتا ہے۔ مل کر وہ Clean Architecture کی بنیاد بناتے ہیں، جو Android پروجیکٹس میں MVP، MVVM اور MVI کے ساتھ استعمال ہوتا ہے۔

SRP: واحد ذمہ داری کا اصول

Single Responsibility Principle (SRP) — واحد ذمہ داری کا اصول۔ تشکیل: «ایک کلاس میں تبدیلی کی صرف ایک وجہ ہونی چاہیے»۔ اس کا مطلب ہے کہ ہر ماڈیول یا کلاس بالکل ایک فعالیت یا ایک ڈومین ہستی کے لیے ذمہ دار ہے۔ اگر کوئی کلاس صارفین اور ای میل بھیجنے دونوں کا انتظام کرتی ہے — تو اس میں تبدیلی کی دو وجوہات ہیں، جو SRP کی خلاف ورزی کرتی ہے۔

Robert C. Martin، 2002 کے مطابق، SRP سب سے اہم اور ساتھ ہی سب سے زیادہ خلاف ورزی کیا جانے والا اصول ہے۔ موبائل ڈیولپمنٹ میں، SRP کی خلاف ورزی اکثر Activity/Fragment میں UI منطق، نیویگیشن، نیٹ ورکنگ اور کاروباری منطق کو ملا کر کی جاتی ہے۔ حل یہ ہے کہ ہر پرت کو علیحدہ کلاس میں نکالا جائے: UI منطق کے لیے ViewModel، ڈیٹا کے لیے Repository، نیویگیشن کے لیے NavController۔

SRP مثال: UserManager کی تقسیم

اس کلاس پر غور کریں UserManager، جو پروفائل لوڈ کرتی ہے، ترتیبات محفوظ کرتی ہے اور ای میل بھیجتی ہے۔ یہ تین مختلف ذمہ داریاں ہیں، جن میں سے ہر ایک کو علیحدہ کلاس میں نکالا جانا چاہیے: UserProfileRepository (لوڈنگ)، UserSettingsStorage (محفوظ کرنا) اور EmailService (بھیجنا)۔ کلائنٹ کوڈ (ViewModel) Dependency Injection کے ذریعے تینوں استعمال کرتا ہے، اور ہر کلاس علیحدہ طور پر آسانی سے آزمائی جا سکتی ہے اور دوسروں کو متاثر کیے بغیر تبدیل کی جا سکتی ہے۔

kotlin
// ❌ SRP کی خلاف ورزی: Activity نیٹ ورک، DB اور UI کے بارے میں جانتی ہے
class ProfileActivity : AppCompatActivity() {
    fun loadProfile() {
        api.getUser() // نیٹ ورک کال
        db.saveUser()    // DB آپریشن
        updateUI()         // UI اپ ڈیٹ
    }
}

// ✅ SRP پر عمل: تہوں کو الگ کیا گیا
class ProfileViewModel : ViewModel() {
    private val repo = UserRepository()
    fun loadProfile() { repo.getUser() }
}

SRP خلاف ورزی کی علامات: 200 سے زیادہ سطروں والی کلاس، مختلف ڈومینز کے طریقے، مختلف وجوہات کی بنا پر بار بار تبدیلیاں۔ Android ڈیولپمنٹ کے لیے اصول آسان ہے: Activity صرف اسکرین لائف سائیکل کو سنبھالتی ہے، ViewModel UI حالت کو سنبھالتا ہے، Repository ڈیٹا ذرائع کو سنبھالتا ہے۔

SRP اور مائیکرو سروس آرکیٹیکچر

SRP اصول نہ صرف کلاسوں پر بلکہ سروس سطح کی آرکیٹیکچر پر بھی لاگو ہوتا ہے۔ ہر مائیکرو سروس ایک ڈومین ہستی کو سنبھالتی ہے: UserService — صرف صارفین، PaymentService — صرف ادائیگیاں، NotificationService — صرف اطلاعات۔ یہ خدمات کی آزادانہ توسیع، تعیناتی اور جانچ کی اجازت دیتا ہے۔ موبائل ایپلیکیشنز میں، مائیکرو سروس سطح پر SRP API کلائنٹس کو ڈومین کے مطابق الگ کرنے میں ظاہر ہوتا ہے۔

OCP: کھلا/بند اصول

Open-Closed Principle (OCP) — کلاسیں توسیع کے لیے کھلی ہونی چاہئیں (نیا رویہ شامل کیا جا سکتا ہے) اور ترمیم کے لیے بند (موجودہ کوڈ تبدیل نہیں کیا جاتا)۔ یہ پولیمورفزم، تجریدی کلاسوں اور انٹرفیسز کے ذریعے حاصل کیا جاتا ہے۔ موجودہ طریقہ میں if-else شامل کرنے کے بجائے، ایک نیا انٹرفیس نفاذ بنایا جاتا ہے۔

Clean Coder Blog، 2014 کے مطابق، OCP Strategy پیٹرن کے ساتھ بہترین کام کرتا ہے۔ مثال کے طور پر، اگر کوئی ایپ مختلف ادائیگی کے طریقوں (Google Pay، Apple Pay، PayPal) کو سپورٹ کرتی ہے، تو ادائیگی پروسیسر میں switch-case شامل کرنے کی ضرورت نہیں ہے۔ ہر ادائیگی کا طریقہ ایک مشترکہ PaymentGateway انٹرفیس کو نافذ کرتا ہے، اور ایک نیا ادائیگی نظام موجودہ کوڈ کو تبدیل کیے بغیر ایک نئی کلاس کے طور پر شامل کیا جاتا ہے۔

kotlin
// ✅ OCP: توسیع کے لیے کھلا، ترمیم کے لیے بند
interface PaymentGateway {
    fun processPayment(amount: Double): Boolean
}

class GooglePayGateway : PaymentGateway {
    override fun processPayment(amount: Double) = true
}

// نیا ادائیگی نظام — موجودہ کوڈ کو تبدیل کیے بغیر
class ApplePayGateway : PaymentGateway {
    override fun processPayment(amount: Double) = true
}

LSP: لِسکوو متبادل اصول

Liskov Substitution Principle (LSP) — Barbara Liskov کا متبادل اصول۔ اگر S، T کی ایک ذیلی قسم ہے، تو T قسم کی اشیاء کو S قسم کی اشیاء سے پروگرام کی خصوصیات کو تبدیل کیے بغیر تبدیل کیا جا سکتا ہے۔ رسمی طور پر: ایک فنکشن جو بنیادی کلاس استعمال کرتا ہے اسے اس کی کسی بھی ذیلی کلاس کے ساتھ صحیح طریقے سے کام کرنا چاہیے۔ اگر کوئی ذیلی کلاس وہاں استثناء پھینکتی ہے جہاں بنیادی کلاس نہیں پھینکتی — LSP کی خلاف ورزی ہوئی ہے۔

Robert C. Martin، 2002 کے مطابق، LSP سب سے مشکل SOLID اصول ہے۔ خلاف ورزی کی کلاسک مثال Square کلاس ہے جو Rectangle سے وراثت پاتی ہے۔ اگر Square میں setWidth چوڑائی اور اونچائی دونوں سیٹ کرتا ہے، تو Rectangle کے رویے کی توقع رکھنے والا کلائنٹ کوڈ غیر متوقع نتیجہ حاصل کرتا ہے۔ موبائل ڈیولپمنٹ میں، LSP کی خلاف ورزی اکثر ViewModel کی وراثت میں ہوتی ہے — جب کوئی چائلڈ ViewModel لازمی انحصار شامل کرتی ہے۔

kotlin
// ❌ LSP خلاف ورزی: Square Rectangle کے رویے کو توڑتا ہے
open class Rectangle(open var width: Int, open var height: Int)

class Square(side: Int) : Rectangle(side, side) {
    override var width
        get() = super.width
        set(value) { super.setBoth(value, value) }
}

ISP: انٹرفیس علیحدگی کا اصول

Interface Segregation Principle (ISP) — کلائنٹس کو ان انٹرفیسز پر انحصار نہیں کرنا چاہیے جو وہ استعمال نہیں کرتے۔ ایک «موٹے» انٹرفیس کے بجائے، کئی تنگ مخصوص انٹرفیسز بنائیں۔ اگر کوئی کلاس کسی انٹرفیس کو نافذ کرتی ہے لیکن کچھ طریقے UnsupportedOperationException پھینکتے ہیں یا خالی رہتے ہیں — یہ ISP خلاف ورزی کی واضح علامت ہے۔

DigitalOcean، 2024 کے مطابق، ViewModel اور Repository ڈیزائن کرتے وقت موبائل ڈیولپمنٹ میں ISP خاص طور پر اہم ہے۔ تمام CRUD طریقوں والے ایک UserRepository انٹرفیس کے بجائے، QueryUserRepository (صرف پڑھنا) اور CommandUserRepository (لکھنا) بنانا بہتر ہے۔ تب صرف پڑھنے والا کلائنٹ (UI عنصر) صرف Query انٹرفیس پر انحصار کرتا ہے اور لکھنے کے طریقوں کے بارے میں کچھ نہیں جانتا۔

kotlin
// ❌ موٹا انٹرفیس — کلائنٹ غیر ضروری طریقوں کو لاگو کرنے پر مجبور
interface UserOperations {
    fun getUser(id: String): User
    fun saveUser(user: User)
    fun deleteUser(id: String)
    fun exportUsers(): File
}

// ✅ ISP: الگ کردہ انٹرفیسز
interface UserReader { fun getUser(id: String): User }
interface UserWriter { fun saveUser(user: User) }
interface UserDeleter { fun deleteUser(id: String) }

DIP: انحصار الٹانے کا اصول

Dependency Inversion Principle (DIP) — اعلیٰ سطح کے ماڈیولز کو ادنیٰ سطح کے ماڈیولز پر انحصار نہیں کرنا چاہیے۔ دونوں کو تجریدات (انٹرفیسز) پر انحصار کرنا چاہیے۔ تجریدات کو تفصیلات پر انحصار نہیں کرنا چاہیے — تفصیلات کو تجریدات پر انحصار کرنا چاہیے۔ یہ «Dependency Injection» (DI) نہیں ہے، اگرچہ DI، DIP کو لاگو کرنے کا ایک عام طریقہ ہے۔

Robert C. Martin، 2019 کے مطابق، DIP Clean Architecture کی بنیاد ہے۔ ViewModel (اعلیٰ سطح) کو براہ راست RetrofitApi (تفصیل) کی مثال نہیں بنانی چاہیے۔ اس کے بجائے، ViewModel UserRepository انٹرفیس پر انحصار کرتا ہے، اور Retrofit کے ساتھ کنکریٹ UserRepositoryImpl کنسٹرکٹر کے ذریعے منتقل کیا جاتا ہے۔ Android میں، DIP کو Hilt/Dagger یا Koin کے ذریعے لاگو کیا جاتا ہے: تمام انحصار DI کنٹینر کے ذریعے فراہم کیے جاتے ہیں۔

kotlin
// ✅ DIP: Module تجرید پر انحصار کرتا ہے، تفصیلات پر نہیں
class UserRepositoryImpl(
    private val api: UserApi,   // انٹرفیس پر منحصر
    private val db: UserDao     // انٹرفیس پر منحصر
) : UserRepository {

    override suspend fun getUser(id: String): User {
        return api.fetchUser(id)
    }
}

// Hilt DI: تفصیلات DI ماڈیول کے ذریعے منسلک ہوتی ہیں
@Module
object NetworkModule {
    @Provides
    fun provideUserApi(retrofit: Retrofit): UserApi =
        retrofit.create(UserApi::class.java)
}

موبائل ڈیولپمنٹ میں SOLID کا اطلاق

موبائل ڈیولپمنٹ میں SOLID تمام سطحوں پر لاگو ہوتا ہے: ایپلیکیشن آرکیٹیکچر سے لے کر انفرادی کلاسوں تک۔ Android پروجیکٹس میں، Clean Architecture کوڈ کو تین تہوں میں تقسیم کرتی ہے: domain (کاروباری منطق — فریم ورک سے آزاد)، data (ذخیرے، API، DB) اور presentation (UI، ViewModel)۔ Domain پرت SOLID اصول استعمال کرتی ہے: استعمال کے معاملات (SRP)، ذخیرہ انٹرفیسز (DIP)، ہستی کلاسیں (OCP + LSP)۔

Android Developers Guide، 2025 کے مطابق، Android میں SRP ViewModel، Repository اور Mapper کو علیحدہ کرنے میں ظاہر ہوتا ہے۔ OCP — DataSource انٹرفیس کے ذریعے نئے ڈیٹا ذرائع شامل کرتے وقت۔ LSP — مختلف ذخیروں میں یکساں Result ہینڈلنگ میں۔ ISP — CQRS طریقہ کار میں (پڑھنے/لکھنے والے ذخیروں کو علیحدہ کرنا)۔ DIP — انحصار انجیکشن کے لیے Hilt/Koin کے ذریعے۔

اصولاس کے بغیر مسئلہموبائل پروجیکٹ میں حل
SRP1000+ سطروں والی ActivityViewModel + UseCase + Repository
OCPادائیگی کی قسم کے مطابق switch-caseStrategy: PaymentGateway انٹرفیس
LSPBaseViewModel تبدیل کرنے پر بگذیلی کلاس معاہدے کی جانچ
ISPUnsupportedOperationExceptionReader / Writer علیحدگی
DIPViewModel دستی طور پر Retrofit بناتا ہےHilt / Koin DI کنٹینر

SOLID لاگو کرتے وقت عام غلطیاں

SOLID غلطیاں اکثر کوڈ کی ضرورت سے زیادہ پیچیدگی سے متعلق ہوتی ہیں۔ پہلی — سیاق و سباق پر غور کیے بغیر اصولوں کی لفظی پیروی کرنا۔ صرف «صاف» ISP کے لیے ایک UserService کلاس کو 10 انٹرفیسز اور 15 کلاسوں میں تقسیم کرنا اوور انجینیئرنگ ہے۔ SOLID ایک آلہ ہے، مقصد نہیں۔ دوسری غلطی — SRP کو «ایک طریقہ = ایک ذمہ داری» سمجھنا۔ ایک کلاس میں کئی طریقے ہو سکتے ہیں اگر وہ سب ذمہ داری کے ایک ہی علاقے سے تعلق رکھتے ہوں۔

Simple Thread، 2024 کے مطابق، تیسری غلطی — Android میں ViewModel کی وراثت میں LSP کو نظر انداز کرنا۔ اگر بنیادی ViewModel LiveData کی توقع کرتی ہے لیکن چائلڈ StateFlow استعمال کرتی ہے — LiveData پر سبسکرائب کردہ کلائنٹ کوڈ اپ ڈیٹس وصول نہیں کرے گا۔ چوتھی — جانچ کے لیے DIP کی خلاف ورزی: RepositoryImpl براہ راست OkHttpClient کی مثال بناتا ہے، جو یونٹ ٹیسٹنگ کو ناممکن بناتا ہے۔

سنہری اصول: SOLID کو اس وقت لاگو کریں جب یہ کسی حقیقی مسئلے (بار بار تبدیلیاں، جانچ میں دشواری، تکرار) کو حل کرتا ہو۔ سادہ CRUD اسکرینوں کے لیے، پانچ اصولوں کی سختی سے پیروی ضرورت سے زیادہ ہے۔ کاروباری منطق، مالی حسابات اور API تعاملات کے لیے، SOLID ضروری ہے۔

SOLID اور Clean Architecture کے درمیان تعلق

Clean Architecture (Robert C. Martin، 2012) — ایپلیکیشن پرت کی سطح پر SOLID کا براہ راست اطلاق ہے۔ SRP استعمال کے معاملات کی حدود متعین کرتا ہے (ہر استعمال کا معاملہ — ایک کلاس)۔ OCP ذخیرہ انٹرفیسز کے ذریعے لاگو ہوتا ہے (Data Layer Domain کو تبدیل کیے بغیر بدل سکتی ہے)۔ ISP استعمال کے معاملے کو ان پٹ/آؤٹ پٹ حدود میں علیحدگی فراہم کرتا ہے۔ DIP — انحصار کی سمت Domain پرت کے اندر کی طرف۔ LSP ضمانت دیتا ہے کہ کوئی بھی ذخیرہ نفاذ استعمال کے معاملات کو توڑے بغیر تبدیل کیا جا سکتا ہے۔

اکثر پوچھے گئے سوالات

سادہ الفاظ میں SOLID کیا ہے؟

SOLID — کوڈ لکھنے کے پانچ قواعد تاکہ اسے تبدیل کرنا، جانچنا اور سمجھنا آسان ہو۔ ہر حرف ایک اصول ہے: بڑی کلاسیں نہ لکھیں (SRP)، موجودہ کوڈ کو تبدیل نہ کریں — نیا شامل کریں (OCP)، ذیلی کلاسوں کے رویے کو نہ توڑیں (LSP) اور دیگر۔

کون سا SOLID اصول سب سے اہم ہے؟

SRP (Single Responsibility) سب سے اہم سمجھا جاتا ہے کیونکہ اس کی خلاف ورزی God کلاسوں — بڑی کلاسوں جن کی جانچ اور تبدیلی مشکل ہے — کی طرف لے جاتی ہے۔ تاہم، DIP (Dependency Inversion) کے بغیر کوڈ مضبوطی سے منسلک رہتا ہے، جو بھی اہم ہے۔

کیا SOLID موبائل ڈیولپمنٹ کے لیے لازمی ہے؟

لازمی نہیں ہے، لیکن طویل زندگی کے چکر والے تجارتی منصوبوں کے لیے انتہائی سفارش کی جاتی ہے۔ سادہ ایپس (ایک اسکرین، کوئی کاروباری منطق نہیں) کے لیے، SOLID ضرورت سے زیادہ ہو سکتا ہے۔ 50+ اسکرینوں اور 3+ ڈیولپرز والے منصوبوں کے لیے، SOLID کم از کم ضرورت ہے۔

اگر SOLID کی پیروی نہ کی جائے تو کیا ہوتا ہے؟

نتائج: کلاسیں «موٹی» ہو جاتی ہیں (1000+ سطریں)، ایک جگہ تبدیلی تین دیگر جگہوں کو توڑ دیتی ہے، یونٹ ٹیسٹ لکھنا ناممکن ہو جاتا ہے، نئی خصوصیت شامل کرنے میں دنوں کے بجائے ہفتے لگتے ہیں۔ وقت گزرنے کے ساتھ، کوڈ «Big Ball of Mud» — الجھا ہوا اور نازک — میں بدل جاتا ہے۔

کیسے جانچیں کہ پروجیکٹ میں SOLID پر عمل ہو رہا ہے؟

عمل کی علامات: ہر کلاس 200 سطروں سے کم، کسی خصوصیت کو تبدیل کرنے سے 5+ فائلیں متاثر نہیں ہوتیں، 10 انحصاروں کو نقل کیے بغیر ٹیسٹ لکھے جا سکتے ہیں، ایک نیا ڈیولپر ایک دن میں ڈھانچہ سمجھ لیتا ہے۔ SonarQube اور detekt جیسے اوزار SRP اور DIP کی خلاف ورزیوں کی نشاندہی کرنے میں مدد کرتے ہیں۔

خلاصہ

  • SOLID — لچکدار اور برقرار رکھنے کے قابل کوڈ بنانے کے لیے پانچ OOP اصول (SRP، OCP، LSP، ISP، DIP)
  • SRP — ہر ہستی ایک کام کے لیے ذمہ دار، God کلاس کے مسئلے کا حل
  • OCP — پولیمورفزم کے ذریعے توسیع، موجودہ کوڈ کی تبدیلی نہیں
  • LSP — ذیلی کلاسوں کو بنیادی کلاس کے رویے کو نہیں توڑنا چاہیے
  • ISP — عالمگیر «سوئس چاقو» کے بجائے تنگ انٹرفیسز
  • DIP — تجریدات پر انحصار، Android میں Hilt/Koin کے ذریعے انجیکشن
  • SOLID Clean Architecture اور تجارتی موبائل منصوبوں کے لیے ضروری ہے

ہم ایک موبائل ایپلیکیشن ٹرنکی تیار کریں گے

IT Sectr 2017 سے اسٹارٹ اپس اور کاروبار کے لیے iOS اور Android ایپلیکیشنز بناتا ہے۔ ہم آپ کو مشورہ دیں گے اور بہترین حل تجویز کریں گے۔

پروجیکٹ پر بحث کریں

مزید پڑھیں