2.2.9 · Coding › Design Principles
Intuition Ek sentence mein idea
Separation of Concerns (SoC) ka matlab hai program ko distinct parts mein todna, jahan har part ek concern handle karta hai (exist karne ki ek reason) aur doosron ke baare mein jitna ho sake utna kam jaanta hai. Aap jo cheezein alag-alag reasons se change hoti hain unhe alag-alag jagah rakhte ho.
Intuition Core problem jo ye solve karta hai
Software isliye fail nahi hota kyunki computers slow hain, balki isliye kyunki insaan ek waqt mein sirf kuch cheezein hi dimag mein rakh sakta hai . Jab ek piece of code validation, database access, business rules, aur UI formatting sab kuch ek saath juggle karta hai, toh ek cheez change karne se baaki sab toot'ne ka risk rehta hai. SoC isliye exist karta hai taaki change local rahe : ek reason se hone wala change ek hi jagah touch kare.
Ek concern problem ka koi bhi aisa distinct aspect hai jiske baare mein aapko parwah hai — jaise "data kaise store hota hai", "prices kaise calculate hote hain", "screen kaisi dikhti hai". Separation ka ulta hai tangling (ek module kai concerns karna) aur scattering (ek concern kai modules mein failna).
Ek concern ek single, cohesive responsibility ya "reason to change" hota hai. Agar do pieces of code ek hi reason se change hote hain, toh woh saath belong karte hain; agar woh alag-alag reasons se change hote hain, toh woh alag belong karte hain.
Definition Separation of Concerns
Ek design principle jo kehta hai ki ek system ko is tarah decompose kiya jaana chahiye ki har module ek separate concern address kare , minimal overlap (low coupling) aur maximal internal focus (high cohesion) ke saath.
Do measurable forces batati hain ki aap succeed hue ya nahi:
Ye dono saath kyun? Kyunki aap akele ek ko cheat kar sakte ho:
Sab kuch ek giant function mein daalo → modules ke beech coupling zero hai (ek hi module hai!) lekin cohesion terrible hai.
50 tiny modules mein split karo jo sab ek doosre ko call karte hain → cohesion high lagti hai lekin coupling explode ho jaati hai.
SoC aapko dono jeetnе ke liye kehta hai concerns ke natural seams pe cut karne se.
Ek practical 3-step recipe:
Change ke reasons list karo. Pucho: "Kaun mujhse ye edit karwaega, aur kyun?" Har distinct jawab ek concern hai. (Ye literally Single Responsibility Principle disguise mein hai.)
Reason se group karo, data se nahi. Jo code saath change hota hai woh saath rehta hai; jo code alag-alag reasons se change hota hai woh alag ho jaata hai.
Ek boundary insert karo (ek function, class, module, ya layer) taaki parts ek narrow interface ke through baat karein, apne internals chupaate hue.
Worked example Tangled se separated tak
Tangled version — ek function fetching, calculating, formatting, aur printing sab karta hai:
def show_total ():
rows = db.query( "SELECT price, qty FROM cart" ) # storage concern
total = sum (p * q for p, q in rows) # business concern
total_with_tax = total * 1.18 # business concern
print ( f "Total: $ { total_with_tax :.2f } " ) # presentation concern
Ye bura kyun hai? Teen reasons to change ek hi jagah mein hain. Database switch karo → yahan edit karo. Tax law change karo → yahan edit karo. Web UI par move karo → yahan edit karo. Har change baaki sabke liye risk ban jaata hai.
Separated version:
def fetch_cart (): # storage concern
return db.query( "SELECT price, qty FROM cart" )
def cart_total (rows, tax = 0.18 ): # business concern
return sum (p * q for p, q in rows) * ( 1 + tax)
def render_total (amount): # presentation concern
return f "Total: $ { amount :.2f } "
# composition:
print (render_total(cart_total(fetch_cart())))
Ye step kyun? Ab cart_total pure logic hai — bina database ke, bina screen ke testable. Tax change sirf cart_total ko touch karta hai. UI change sirf render_total ko touch karta hai. Har concern ka ek ghar hai.
Worked example Layered architecture as SoC at scale
Ek classic web app:
Presentation layer — cheezein kaisi dikhti hain (HTML/JSON).
Application/Service layer — use-cases orchestrate karta hai.
Domain layer — business rules (software ka kyun ).
Data layer — persistence.
Ye exact layers kyun? Har layer alag reason se change hoti hai (UI fashion, naye features, business policy, database tech). Arrows ek direction mein point karte hain (presentation → domain → data) taaki database swap kabhi UI rewrite force na kare. Woh one-directional dependency SoC ko structural bana deti hai.
Worked example Layers se aage — orthogonal concerns
Kuch concerns har layer ko cross karte hain: logging, security, error handling. Inhe cross-cutting concerns kehte hain. Hum inhe middleware , decorators , ya aspect-oriented techniques se separate karte hain taaki business code clean rahe.
def with_logging (fn): # the cross-cutting concern, isolated
def wrapped ( * a, ** k):
log( f "calling { fn. __name__} " )
return fn( * a, ** k)
return wrapped
@with_logging
def cart_total (rows): ...
Ye step kyun? Logging ek concern hai; cart_total ka math doosra concern hai. Decorator unhe physically alag rakhta hai, bhaale woh saath run karte hain.
Common mistake "Maine ise kai files mein split kiya, toh concerns separated hain."
Ye sahi kyun lagta hai: zyada files organized aur modular lagti hain .
Ye galat kyun hai: agar a.py calls b.py calls c.py aur ek single business change teeno mein edits force karta hai, toh concern scatter hua tha, separate nahi. File count ≠ separation.
Fix: test karo ye puchke ki "ek typical change ke liye main kitni jagah edit karta hoon?" Good SoC → ideally ek .
Common mistake "One concern" ko "one line / one tiny function" samajhna.
Ye sahi kyun lagta hai: SRP/SoC "ek cheez" karne ki baat karte hain.
Ye galat kyun hai: "ek cheez" ka matlab change ka ek reason hai, na ki ek statement. Over-splitting fragmentation create karta hai — high coupling aur tiny pieces ka ek maze.
Fix: reason to change se group karo, size se nahi.
Common mistake "Separation ka matlab hamesha zyada layers hain."
Ye sahi kyun lagta hai: badi architectures mein kai layers hoti hain.
Ye galat kyun hai: unnecessary layers ek tiny script ke liye coupling aur indirection add karte hain. SoC real seams pe cut karne ke baare mein hai, na ceremony add karne ke baare mein.
Fix: boundary tabhi add karo jab do concerns genuinely independently change hote hain.
Recall Ek "concern" kya hai, aur uska cleanest test kya hai?
Concern = change ka ek reason . Test: "Kaun mujhse ye edit karwaega, aur kyun?" Har distinct jawab ek separate concern hai.
Recall Coupling minimize karo AUR cohesion maximize karo, sirf ek nahi — kyun?
Akele kisi ek ko optimize karna gameable hai: ek giant module = zero module-coupling lekin cohesion koi nahi; kai tiny chatty modules = "high cohesion" lekin exploding coupling. SoC dono jeetta hai natural concern boundaries pe cut karke.
Recall Cross-cutting concern kya hota hai aur ise kaise separate karte hain?
Ek concern (logging, auth, error handling) jo kai modules ko touch karta hai. Decorators/middleware/aspects ke zariye separate kiya jaata hai taaki business logic clean rahe.
Recall (Feynman, age 12) Ise simply explain karo.
Sochो ek kitchen jahan ek insaan ek saath kaatata, pakaata, plate karta, aur bartan dhoota hai — jab recipe change hoti hai, toh woh confused ho jaata hai aur khana jala deta hai. Separation of concerns matlab har kaam ek alag insaan ko dena: kaatne wala sirf kaata hai, pakaane wala sirf pakata hai. Ab agar aap dish change karo, sirf cook kuch naya seekhta hai — baaki sab apna simple kaam karte rehte hain. Software bhi aisa hi hai: code ke har piece ko ek kaam do taaki ek cheez change karne se sab kuch nahi toote.
"One reason, one room."
Har concern ko apna ek room milta hai (module). Agar do cheezein alag-alag reasons se bahar jaati hain, toh woh ek room share nahi karti.
Separation of Concerns ka matlab hai ki har module handle karta hai ek concern (change ka ek reason), doosron ke saath minimal overlap ke saath.
Ek "concern" ko best define kiya jaata hai change ka ek single reason / ek cohesive responsibility.
Do metrics jo good SoC indicate karte hain low coupling aur high cohesion.
Coupling measure karta hai kitne doosre modules par ek module depend karta hai (LOW chahiye).
Cohesion measure karta hai ek module ke elements kitne focused hain ek concern par (HIGH chahiye).
Hum coupling AUR cohesion dono saath optimize kyun karte hain dono akele gameable hain; SoC dono achieve karta hai natural concern boundaries pe cut karke.
Tangling (anti-pattern) ka matlab hai ek module kai concerns mix karna.
Scattering (anti-pattern) ka matlab hai ek concern kai modules mein failna.
Cross-cutting concern hota hai ek concern (logging, security, error handling) jo kai modules mein spread hota hai.
Cross-cutting concerns separate kiye jaate hain decorators, middleware, ya aspect-oriented programming se.
Layered architecture mein dependencies point karni chahiye ek direction mein (presentation → domain → data).
Good separation ka sabse quick practical test ek typical change ideally ek hi jagah edit karna require kare.
SoC, SRP se relate karta hai kyunki SRP, SoC ko class level par apply karta hai (ek class = change ka ek reason).
SoC mein "ek cheez" ka matlab hai change ka ek reason, NA ki ek line/ek tiny function.
Single Responsibility Principle — SoC ek single class/module par apply hota hai.
Coupling and Cohesion — good SoC ka measurable outcome.
Layered Architecture — SoC horizontal layers ke roop mein realize hota hai.
Cross-cutting concerns — jo concerns simple layering se resist karte hain.
Modularity — broader goal jisko SoC serve karta hai.
Don't Repeat Yourself (DRY) — SoC ke saath pair karta hai; har concern ka ek ghar hota hai.
Information Hiding — woh boundary jo separation ko hold karvati hai.
Concern one reason to change
Tangling one module many concerns
Scattering one concern many modules
Single Responsibility Principle
Narrow interface boundary