2.2.7 · Coding › Design Principles
Kisi bhi client ko aisi methods par depend karne ke liye force nahi karna chahiye jo wo use nahi karta. Fat interfaces ko chote, role-specific interfaces mein split karna chahiye taaki har implementer sirf wahi "sign up" kare jo use actually chahiye.
Definition Interface Segregation Principle
SOLID mein I . Iska kehna hai: bahut saare client-specific (chhote) interfaces ek general-purpose (fat) interface se behtar hain . Kisi class ko kabhi bhi aisi methods implement karne ke liye force nahi kiya jaana chahiye jo use care nahi karti.
Yahan client ka matlab hai wo code jo interface par depend karta hai — caller BHI aur implementer BHI. Jab ek interface unrelated capabilities ko bundle karta hai, toh har implementer un sab mein ghich jaata hai.
Intuition Fat interfaces kyun hurt karte hain
Jab Worker work() AUR eat() declare karta hai, toh ek RobotWorker ko eating ka koi notion nahi hota. Use eat() implement karne ke liye force kiya jaata hai — usually ek stub ke saath ya, aur bura, throw new UnsupportedOperationException() ke saath. Ye ek jhooth hai: type claim karti hai ek aisi ability jo uske paas hai nahi.
Fat interfaces ke teen concrete pains:
Forced dummy implementations → dead code, type system mein jhooth.
Coupling by accident — eat() ka signature change karo aur har worker recompile hoga, robots bhi.
Misleading contracts — callers trust nahi kar sakte ki koi method actually kaam karti hai.
Intuition ISP ≈ "interfaces ke liye SRP" kyun hai
Single Responsibility kehta hai ek class ka ek hi reason to change hona chahiye. ISP kehta hai ek interface ka ek hi reason to change hona chahiye. Fat interface bahut saare clients ko serve karta hai → bahut saare reasons to change → instability.
Worked example ISP ka violation
interface Worker {
void work ();
void eat (); // not all workers eat!
}
class RobotWorker implements Worker {
public void work () { /* assemble cars */ }
public void eat () { throw new UnsupportedOperationException (); } // ❌ lie
}
Ye bura kyun hai? RobotWorker ko eat() par depend karne ke liye force kiya ja raha hai. Koi bhi code jo robot par worker.eat() call karta hai wo runtime par crash karta hai — compiler warn nahi kar sakta tha.
Worked example ISP se fix kiya
interface Workable { void work (); }
interface Feedable { void eat (); }
class HumanWorker implements Workable , Feedable {
public void work () { ... }
public void eat () { ... }
}
class RobotWorker implements Workable { // ✅ only what it needs
public void work () { ... }
}
Ye step kyun? Ek canteen scheduler ab sirf Feedable par depend karta hai. Ye RobotWorker ko refer bhi nahi kar sakta , toh bug class compile time par hi gayab ho jaati hai.
Worked example Fat interface
interface Machine {
void print (Doc d );
void scan (Doc d );
void fax (Doc d );
}
Ye kyun fail karta hai: Ek OldPrinter jo sirf print kar sakta hai use fir bhi scan aur fax implement karne padenge. Aur bura, Machine mein koi nayi method add karo (jaise staple()) toh har machine break ho jaayegi.
Worked example Segregated
interface Printer { void print (Doc d ); }
interface Scanner { void scan (Doc d ); }
interface Fax { void fax (Doc d ); }
class OldPrinter implements Printer { ... }
class AllInOne implements Printer , Scanner , Fax { ... }
Ye step kyun? Roles ka composition. OldPrinter ka contract ab honest hai, aur staple() ko interface Stapler ke roop mein add karna kisi ko touch nahi karta jo staple nahi karta.
Worked example Forced dependencies count karna
Maano ek fat interface mein m methods hain aur n implementers hain, jahan implementer i genuinely u i methods use karta hai. Forced (unused) method dependencies ki sankhya hai
F fat = ∑ i = 1 n ( m − u i ) .
Ye formula kyun? Har implementer ko saare m methods satisfy karne padte hain lekin sirf u i ki zaroorat hoti hai; gap m − u i forced dead weight hai. Perfect segregation ke baad har implementer exactly u i pull karta hai, toh F seg = 0 .
Numbers: m = 3 (print/scan/fax), implementers { 1 , 1 , 3 } methods use karte hain.
F fat = ( 3 − 1 ) + ( 3 − 1 ) + ( 3 − 3 ) = 2 + 2 + 0 = 4 forced dependencies ISP se hataaye gaye.
Common mistake "Zyada interfaces = zyada ISP, toh EVERY method split karo."
Ye sahi kyun lagta hai: ISP chote interfaces ko reward karta hai, toh har ek method ke liye alag interface banana maximally compliant lagta hai.
Fix: Split karo cohesive role / client need se, individual method se nahi. read() aur write() jo hamesha same client ke saath use hote hain wo ek Stream interface mein belong karte hain. Over-splitting interface explosion create karta hai aur intent obscure karta hai. Cohesion goal hai, minimal size nahi.
Common mistake "UnsupportedOperationException throw karna interface ko satisfy karta hai."
Ye sahi kyun lagta hai: Ye compile hota hai aur class technically sab kuch "implement" karti hai.
Fix: Ye Liskov contract violate karta hai — callers ek working method expect karte hain. Ek compile-time stub ek runtime bomb hai. Isliye method ko interface se hi hata do.
Common mistake "ISP aur SRP same hain."
Ye sahi kyun lagta hai: Dono kehte hain 'cheezein choti rakho / ek responsibility.'
Fix: SRP ek class ke reasons to change ke baare mein hai; ISP callers ko kya depend karne ke liye force kiya jaata hai ke baare mein hai. Ek class ki ek responsibility ho sakti hai lekin fir bhi different clients ke liye ek bloated interface expose kar sakti hai.
Recall Feynman: ek 12-saal ke bachche ko samjhao
Socho ek restaurant menu jo tumhe force karta hai soup, salad AUR dessert saath order karne ke liye, chahe tumhe sirf soup chahiye. Annoying hai, na? Ek achha menu tumhe sirf jo chahiye wo pick karne deta hai. Ek interface ek menu hai un cheezeon ka jo ek piece of code kar sakta hai. ISP kehta hai: code ko aisi abilities "order" karne ke liye force mat karo jo kabhi use nahi hogi — use sirf apni dishes wala chhota menu do.
"Mujhe wo buttons mat pakda jo main kabhi press nahi karunga."
Socho ek TV remote jisme 80 buttons hain jabki tum sirf 4 use karte ho — ye ek fat interface hai. ISP = har task ke liye ek tiny remote.
ISP ko ek sentence mein state karo — phir upar di gayi definition se check karo.
throw new UnsupportedOperationException() ek code smell kyun hai jo ISP violation point karta hai?
ISP aur SRP mein kya fark hai?
SOLID mein I ka kya matlab hai? Interface Segregation Principle.
Interface Segregation Principle state karo. Kisi bhi client ko aisi methods (interface members) par depend karne ke liye force nahi karna chahiye jo wo use nahi karta.
Code mein ISP violation ka core symptom kya hai? Implementers empty/dummy methods likhte hain ya un methods ke liye UnsupportedOperationException throw karte hain jo wo use nahi karte.
"Role interface" kya hota hai? Ek chhota interface jo us hisaab se define hota hai ki ek specific client ko kya chahiye, sirf cohesive methods ko group karta hai jo saath use hote hain.
ISP fix: fat interface ko kis criterion se split karein? Cohesive client role/need se — individual method se NAHI (over-splitting avoid karo).
ISP aur SRP mein kya fark hai? SRP ek class ke reasons to change ko limit karta hai; ISP limit karta hai ki ek client kya depend karne ke liye force hota hai. ISP "interfaces ke liye SRP" hai.
m methods aur implementer i ke u_i use karne par, fat interface kitni forced dependencies impose karta hai? i ke over sum of (m - u_i); segregation ise 0 tak reduce karta hai.
Kaunsa doosra SOLID principle violate hota hai jab ek interface method ko exception ke saath stub kiya jaata hai? Liskov Substitution Principle (subtype supertype ka contract tod deta hai).
Interface Segregation Principle
Client depends only on what it uses
Forced dummy implementations
Recipe: group methods by role
Class implements multiple small interfaces