01Software Architecture kya hai?
Pichle weeks me humne design banana seekha — modular design, layered design, UML diagrams. Ab jab code likhna shuru ho gaya hai, toh big picture view lena zaroori hai — yahi kaam software architecture karta hai.
Google Search Engine aur ek Compiler — dono software systems hain. Inme key differences kya hain? (Pause karke socho... answer neeche hai 👇)
Architecture Styles — 4 types yaad rakhne hain
Jab components ke beech information flow ka pattern alag hota hai, toh use hum alag architecture style kehte hain. Yahi upar wale reflection spot ka answer hai — Google Search aur compiler ka information flow bilkul alag hai.
① Client-Server
Data is transacted in response to requests. User (client) request bhejta hai, server response deta hai. Example: Google Search — aap query type karte ho, request Google ke server pe jaati hai, server pages return karta hai. Aaj ka Internet predominantly aise hi kaam karta hai.
② Pipe and Filter
Data is passed from component to component, and transformed & filtered along the way. Example: Compiler — source code → assembly code → executable file. Har stage pe data transform hota hai, jaise pipeline me paani filter hota jaata hai.
③ Model-View-Controller (MVC)
Is style me views of the data are separated from the manipulations of data. Teen components hote hain (Amazon Seller Portal example ke saath):
- Model — data ko model karta hai. Seller portal me: database ki tables ko model karne wali classes/objects.
- View — GUI objects / presentation layer — Model ka visual representation. Model se data retrieve karke user ko dikhata hai, aur user ↔ model ke beech requests pass karta hai.
- Controller — screen pe multiple views ko coordinate karta hai aur users ko model manipulate karne me help karta hai. Example: seller portal me "filter catalogue items by name" — controller user input receive karne wale module ko message bhejta hai, aur underlying views ko appropriate messages deta hai.
④ Peer-to-Peer (P2P)
Distributed application — alag-alag systems nodes bante hain aur ek-dusre ke saath resources share karte hain. Sabse badi baat: koi centralised system nahi hota jo saare transactions monitor kare. Nodes apni processing power, disk storage etc. directly baaki nodes ko available karate hain — bina kisi central server ya stable host ke.
Client-server se difference: wahan ek central server hota hai; yahan sab barabar (peers) hain.
Components, Connectors, Protocols — architecture ki building blocks
Design Patterns, Anti-patterns, Design Smells, Refactoring
Components kaise banaye jaate hain? Purane zamane me experienced designers past me kaam kar chuke solutions ko consciously reuse karte the (module libraries). Baad me ye solutions standardise ho gaye — inhe hi design patterns kehte hain (famous book: "Design Patterns: Elements of Reusable Object-Oriented Software").
- Design Pattern — description of communicating objects and classes, customised to solve a general design problem in a particular context.
- Anti-pattern — jab achhe intentions ke bawajood pattern galat use ho jaaye ya naya code aate-aate design bigad jaaye. Code me bahut problems create karta hai.
- Design Smell — warning signs ki aapka code anti-pattern ki taraf jaa raha hai. (Naam funny hai but exam me aata hai! 😄)
- SOLID Guidelines — design smells se bachne ke effective guidelines.
- Refactoring — design smell dikhe toh wapas achhe design ki taraf jaana. Isme 3 cheezein: (a) moving code between classes, (b) creating new classes/modules, (c) removing classes that aren't required.
02SOLID Principles
Object-oriented principles for effective software design — inhe conceptualise kiya Robert Martin (Uncle Bob) ne, jo Agile Manifesto ke founders me se ek hain. Ye principles code ko easy to understand aur modular banate hain, aur good cohesion + loose coupling ko support karte hain.
S — Single Responsibility Principle (SRP)
Lecture example (violation): Ek hi Seller class me sab
kuch bhara hai — seller ki info (sellerID, name, address), product ki info, aur inventory ke
functions (addSeller, deleteSeller, addProduct, addItemsToInventory, viewInventory...). Yeh SRP
ko violate karta hai kyunki ek class 3 kaam kar rahi hai.
Refactor (fix): Badi Seller class ko 3 alag classes me split karo:
Seller— sirf seller details + addSeller, deleteSellerProduct— sirf product details + product functionsInventory— sellerID leta hai, products seller ki inventory me add hote hain
O — Open-Closed Principle (OCP)
Matlab: class ka behaviour extend karo (subclass banao), par existing class ko modify mat karo.
Lecture example: Product class hai (id, name, type,
cost). Ab naya product type Clothing add karna hai jisme size aur colour bhi
chahiye.
- ❌ Galat tareeka: Product class me hi size, colour attributes aur naya addProduct() ghusa do → existing class modify ho gayi → OCP violated.
- ✅ Sahi tareeka:
Clothingnaam ki nayi class banao joProductko inherit kare. Clothing ko parent ke saare attributes milenge + apne specialised (size, colour). Product class untouched rahi!
// OCP applied — Product ko chhua hi nahi class Clothing extends Product { String size, colour; // specialised attributes void addProduct(id, name, type, cost, size, colour) { ... } } class Book extends Product { // kal ko Book aaya? bas nayi class! String author, publisher; }
L — Liskov Substitution Principle (LSP)
Lecture example: Feature — sellers ko product feedback ki notification bhejni hai.
- Abstract class
FeedbackNotificationme method:notify(product, feedback, email).EmailNotificationise extend karke email bhejta hai — sab theek. ✅ - Ab SMS bhi bhejna hai.
SMSNotificationbanaya... par problem! Base class ke notify() me teesra parameter email hai, jabki SMS ko mobile number chahiye. Derived class ka method base class se substitute nahi ho sakta → ❌ LSP violated. - ✅ Fix: Email parameter ko abstract class se hata do — notify() sirf (product, feedback) le. Email/mobile number jaisi specific cheezein derived classes apne constructor se set karein: EmailNotification(email), SMSNotification(mobileNo, carrier). Ab dono ka notify() same signature — fully substitutable. ✅
I — Interface Segregation Principle (ISP)
Pehle interface kya hai? — Group of related methods with empty bodies. Interface batata hai kya karna hai, kaise nahi. Dusri classes interface implement karti hain — matlab uske saare methods ki definition likhni padti hai.
Lecture example: DeliveryProcessing interface me 4
methods: placeOrder, notifySeller, packageOrder, deliver. Physical orders ke liye theek hai. Par
digital product (e-book) ke order me packaging aur physical delivery
irrelevant hai — phir bhi client ko woh methods implement karne padenge
(bekaar/meaningless implementations). ❌ ISP violated.
✅ Fix — interface ko segregate (split) karo:
PhysicalDeliveryProcessing— placeOrder, notifySeller, packageOrder, deliver (chaaron)OnlineDeliveryProcessing— sirf placeOrder, notifySeller
Ab jo client jo delivery implement karna chahe, wahi interface use kare. Har interface ek specific function perform kare — koi bhi client ko faltu methods implement na karne padein.
D — Dependency Inversion Principle (DIP)
Lecture example: Feature — seller ko portal pe beche gaye products ka payment milna chahiye.
- ❌ Problem:
Sellerclass ka ek attribute haiBankAccountobject → seller tightly coupled hai bank account se. Ab seller S2 ko UPI se payment chahiye? Toh Seller me UPI ka bhi attribute add karo... phir Google Pay, Paytm... har payment method ke liye Seller class me coupling badhti jayegi → code unnecessarily complex. - ✅ Fix: Ek interface banao
PaymentAccount(method: payment()). Ab Seller sirf is interface se coupled hai. BankAccount, UPI, GooglePay, Paytm — sab is interface ko implement karte hain.
// DIP applied interface PaymentAccount { void payment(); } class BankAccount implements PaymentAccount { ... } class UPI implements PaymentAccount { ... } // main me: jo bhi option chahiye, wahi object banao aur seller ko de do PaymentAccount pa = new UPI(); seller.setPaymentAccount(pa); // seller ko fark nahi padta andar kya hai
03Design Patterns
Elements of a Design Pattern (3 cheezein)
- 1. Problem — pattern kab apply karna hai, kis context me.
- 2. Solution — design ke elements, unke relationships, responsibilities aur collaborations. Ye ek template hai jo alag-alag situations me apply ho sakta hai.
- 3. Consequences — results, trade-offs, cost-benefit. Pattern lagane se pehle socho: fayda hai bhi ya nahi?
3 Types of Design Patterns
| Type | Kya karta hai | Is course me covered |
|---|---|---|
| Creational | Object creation ke process me use hota hai — flexibility + code reuse | Factory, Builder |
| Structural | Objects/classes ko larger structures me assemble karna — flexible & efficient rakhte hue | Facade, Adapter |
| Behavioral | Objects ke beech effective communication + responsibilities ka distribution | Iterator, Observer, Strategy |
🏭 Creational Patterns
Problem: Seller portal me feature — "package ko ek courier service
se deliver karna hai." Simple code: Delivery class (method:
deliver(courier)) + Courier class; main me courier object
banao, delivery ko pass karo. Ab business bada hua — international
courier bhi chahiye. Aasan (par galat) fix: Courier me courierType rakho aur deliver() me if national ... else international ... likho. Ye
Open-Closed Principle violate karta hai — hum existing class modify kar
rahe hain!
Solution: Replace direct object construction calls (new operator) with calls to a special factory method.
DeliveryaurCourierko abstract banao.- Har type ke liye subclasses:
NationalCourier,InternationalCourier(Courier extend karte hain) aurNationalDelivery,InternationalDelivery(Delivery extend karte hain). - Delivery me abstract method
createCourier()— yehi factory method hai. NationalDelivery ka createCourier() → NationalCourier object return karta hai; InternationalDelivery ka → InternationalCourier. - Object banane ki responsibility delegate ho gayi in classes ke
factory method ko. Main me: delivery object banao,
d.createCourier()bulao, jo courier mile use deliver() me do.
// Factory pattern ka core idea abstract class Delivery { abstract Courier createCourier(); // ← FACTORY METHOD void deliver(Courier c) { ... } } class InternationalDelivery extends Delivery { Courier createCourier() { return new InternationalCourier(); } }
Naya type (local courier) add karna ho? Bas nayi classes banao + factory method — koi existing class modify nahi hoti.
✓ Pros
- SRP follow hota hai — har class ek kaam, creation delegate
- OCP follow hota hai — extension by new classes, no modification
✗ Cons
- Code complicated ho sakta hai — bahut saari nayi subclasses banani padti hain
- Context dekh ke trade-off decide karo
Problem: Book object banana hai — kuch
parameters mandatory (ISBN, title, cost) aur kuch
optional (author, published, description). Har combination ke liye
alag constructor likhna padta hai — is problem ko Telescoping
Constructors kehte hain (exam keyword!). Code ganda + complicated.
Solution: Extract the object construction code out of its own class and move it to a separate object called a builder.
Builderclass banao (Book ke andar static class) — same fields.- Builder ka constructor sirf mandatory params leta hai (ISBN, title, cost).
- Har optional field ke liye alag method: author(), published(), description() — jo field set karke builder return karti hai.
- Last me
build()method — final Book object return karta hai. Book ka ab ek hi constructor hai jo builder leta hai.
// step-by-step object banao Book b1 = new Book.Builder("978-93", "SE Notes", 450) .author("Iyer").published(2024).description("...") .build(); Book b2 = new Book.Builder("978-94", "DSA", 300) .description("desc only").build(); // baaki null
✓ Pros
- Objects step by step construct hote hain — lambi constructor calls nahi
- SRP — object creation ka kaam builder ka, baaki class apna kaam kare
✗ Cons
- Code complicated — same params wali extra Builder class + methods
- Mandatory/optional params kam hain toh pattern skip kar sakte ho
🧱 Structural Patterns
Problem: Buyer order place kare toh system ko 4 kaam karne hain: create order → notify seller → prepare packaging → send for delivery. Client ko 4 classes ke objects banane + sahi order me methods bulane padte hain. Client ko itni details kyun pata honi chahiye? Complicated library functions use karne walon ka bhi yahi dard hai.
Solution: Facade provides a simple interface to a library or a
complex set of classes. Ek nayi class banao — DeliveryFacade — jiska ek method (deliver()) saare object creation + function calls apne andar
kar leta hai. Client bas facade ka ek method bulaye, kaam done!
class DeliveryFacade { void deliver(product, sellerName) { new Order().placeOrder(product); new Seller().notifySeller(sellerName); new Package().packageOrder(); new Delivery().deliverOrder(); // sab ek jagah } }
✓ Pros
- Code/libraries ki complexity isolate ho jaati hai — client ko sirf ek simple method dikhata hai
✗ Cons
- Facade baaki objects se tightly coupled hota hai — kisi bhi class me change hua toh facade bhi update karna padega → maintenance difficult
Problem: Seller portal me kuch products ki cost
dollars/euros me hai — rupees me conversion chahiye. Ek existing
library/class hai ConversionCalculator jis par
hamara control nahi hai, aur uska interface Product class ke saath incompatible hai —
Product directly use nahi kar sakta.
Solution: Beech me ek adapter class daalo — ye ek wrapper hai jo client aur adaptee ke beech link provide karta hai. Client adapter ka method bulata hai → adapter andar hi andar adaptee ka (incompatible) method bulata hai. Incompatibility ka saara jhanjhat adapter handle karta hai — client ko complexity pata hi nahi chalti.
// CostCalculatorAdapter = bridge between Product & ConversionCalculator class CostCalculatorAdapter { double getCostInRupees(Product p) { ConversionCalculator cc = new ConversionCalculator(); return cc.dollarToRupee(p.cost); // $300 → ₹ me convert } }
Product ko ConversionCalculator ki koi detail nahi pata — woh sirf adapter se baat karta hai. (Real life analogy: charger ka plug adapter — US plug ko Indian socket me lagane wala!)
✓ Pros
- SRP — currency conversion ka code, product ke business logic se alag
- OCP — nayi currencies ke liye naye adapters easily add ho jaate hain
✗ Cons
- Code complexity badhti hai — naya class + methods; agar Product ya calculator me hi change kar sakte toh adapter ki zaroorat nahi thi
🤝 Behavioral Patterns
Problem: Hum alag-alag collections use karte hain — lists, queues, stacks, trees (products ki list, orders ki list, deliveries ki list...). Common operation: elements ko access aur iterate karna. Client ko sirf elements chahiye — elements kaise store hain (underlying data structure), usse client ko matlab nahi.
Solution: Elements ko access karne ka behaviour ek alag object — iterator — me nikaal do. Java ka Iterator interface ke 2 key methods:
hasNext()— true return karta hai agar iteration me aur elements hainnext()— iteration ka agla element return karta hai
ArrayList ho ya LinkedList — dono in methods ki apni implementation dete hain. Client ko implementation details jaanne ki zaroorat nahi; woh bas hasNext()/next() use kare. Collection badal do, client ka loop same rahega!
✓ Pros
- SRP — element access ka kaam alag iterator class me
- OCP — naye type ka iterator banake naye collections iterate kar sakte ho
✗ Cons
- Simple collections (jaise chhota array) ke liye alag iterator class overkill hai
Problem: Naya product launch ho toh sirf subscribed buyers ko notify karna hai — saare users ko nahi. (YouTube analogy: channel subscribe + bell icon 🔔 → naya video aate hi notification.)
Solution: Subject object ek list of observers maintain karta hai; jab bhi update ho, subject saare observers ko notify kar deta hai.
Subjectclass — observers ka collection; methods: registerObserver(), unregisterObserver(), notifyObservers()Observer— interface/abstract class with update() method- notifyObservers() bas collection pe iterate karke har observer ka update() bula deta hai
- Lecture example:
NormalUseraurPrimeUserdono Observer extend karte hain — normal user ko "naya product aaya" message, prime user ko extra "aapko additional discount bhi milega" 😎 — har type apna update() implement karta hai
✓ Pros
- Sirf interested (subscribed) observers ko hi updates jaate hain
- Naye types ke observers easily add — bas update() implement karo
✗ Cons
- Subject-observer management ka extra structure maintain karna padta hai
Problem: Shopping orders ko alag-alag strategies se
process karna hai — (a) First In First Out (FIFO): jo order pehle
aaya, pehle process; (b) Priority: prime/super users ke orders
pehle. Bina pattern ke: OrderManager me har strategy ka
apna method (deliverFIFO(), deliverPriority()...). Nayi strategy aayi? Class me naya
method add karo → OCP violated (existing class modify ho rahi hai).
Solution: Alag-alag strategies/algorithms ko separate classes me extract karo. Original class (context) algorithm ka kaam strategy object ko delegate kar deti hai.
- Interface:
OrderDeliveryStrategy— methoddeliverOrders() FIFOOrderDeliveryaurPriorityOrderDelivery— dono interface implement karte hain, apna-apna logic deliverOrders() me- Runtime pe strategy switch kar sakte ho: pehle FIFO se deliver kiya, phir priority se — bas naya strategy object do
- Nayi strategy? Nayi class banao jo interface implement kare — existing code me zero changes ✅
✓ Pros
- Algorithm ki implementation details isolate — har class me ek specific strategy ka logic
- OCP — nayi strategies bina existing classes/methods badle add hoti hain
✗ Cons
- Agar sirf 1-2 hi strategies hain toh pattern lagana zaroori nahi — overkill
04Practice Questions (with answers)
Lecture content ke basis pe assignment-style questions banaye hain — MCQ + short answer, IITM graded assignment ke pattern me. "Show Answer" pe click karke check karo. ⚠️ Note: official graded assignment ka PDF project files me nahi tha — woh upload kar doge toh exact questions ke solutions bhi add kar dunga.
Ek compiler source code ko assembly me, phir executable me transform karta hai. Ye kaunsa architecture style hai?
- Client-Server
- Pipe and Filter
- Peer-to-Peer
- MVC
Data ek component se dusre me pass, transform aur filter hota hai. Google Search jaisa request-response nahi hai — isliye client-server nahi.
Google Search Engine kis architecture style ka example hai, aur kyun?
User query type karta hai → request Google ke server pe jaati hai → server related pages ka response return karta hai. "Data transacted in response to requests" — classic client-server. Internet aaj predominantly aise hi chalta hai.
Amazon Seller Portal me database ki tables ko model karne wali classes MVC ke kis component me aati hain?
- View
- Controller
- Model
- Connector
Model = service ke liye required data ko model karne wala component. View = GUI/presentation, Controller = views coordinate + user ko model manipulate karne me help.
Fill in the blanks: Components ke beech information transmit karne wala code ______ kehlata hai, aur unke interaction ke pre-defined rules ______ kehlate hain.
Common connectors: function calls, REST API calls. Protocol ensure karta hai ki client aur server message format pe agree karein.
"Warning signs that your code may be heading towards an anti-pattern" — is definition ko kya kehte hain? Aur isse bachne ke liye kya follow karte hain?
Smell dikhe toh refactoring karo: code move karo classes ke beech, nayi classes/modules banao, ya faltu classes hatao.
Ek Seller class me addSeller(), addProduct(),
viewInventory() — teeno methods hain. Kaunsa principle violate ho raha hai, aur fix kya hai?
Class ke paas 3 responsibilities hain (seller, product, inventory). Fix: 3 alag classes me split karo — Seller, Product, Inventory — har class ek hi kaam kare.
Product class me clothing ke liye size/colour attributes directly add kar diye. Kaunsa principle toota? Sahi approach kya thi?
Existing class ko modify kiya — jabki OCP kehta hai "open for extension,
closed for modification". Sahi approach: Clothing extends Product — nayi subclass, parent untouched.
Base class ke notify(product, feedback, email) ko SMSNotification override nahi kar paa raha kyunki use mobile number chahiye. Ye kis principle ka violation hai? Fix batao.
Derived class base class se substitutable nahi rahi. Fix: email param base class se hatao — notify(product, feedback) rakho; email/mobileNo har derived class apne constructor se set kare.
DeliveryProcessing interface me packageOrder() aur deliver() hain, par e-book (digital product) wale client ke liye ye irrelevant hain. Principle + fix?
"Do not force any client to implement an interface which is irrelevant to them."
Fix: interface ko split karo — PhysicalDeliveryProcessing (chaaron methods) aur OnlineDeliveryProcessing (sirf placeOrder + notifySeller).
Seller class ke paas directly BankAccount object hai. Naye payment methods (UPI, GPay) add karne me problem aa rahi hai. Kaunsa principle apply karein aur kaise?
"Prefer abstractions over implementations." PaymentAccount
interface banao; Seller sirf interface se couple ho;
BankAccount/UPI/GPay/Paytm sab interface implement karein. Naya option = bas nayi class.
SOLID ka full form likho aur ye kisne conceptualize kiye?
Single Responsibility, Open-Closed, Liskov Substitution, Interface Segregation, Dependency Inversion — by Robert Martin (Uncle Bob), Agile Manifesto ke founders me se ek. Ye good cohesion + loose coupling support karte hain.
Factory design pattern ka core idea kya hai, aur ye kaunse 2 SOLID principles follow karta hai?
Core idea: direct object construction (new) ko replace karo special factory method ki calls se — object creation ki responsibility delegate ho jaati hai. Follows: SRP + OCP. Con: bahut saari subclasses se code complicated ho sakta hai.
"Telescoping constructors" problem kya hai aur kaunsa pattern ise solve karta hai?
Mandatory + optional params ke har combination ke liye alag constructor
likhna padta hai — yehi telescoping constructors. Builder pattern construction code ko
alag builder object me le jaata hai: mandatory params constructor me,
optional fields individual methods se, aur build() final object
return karta hai.
Facade pattern ka main disadvantage kya hai?
- Client ko zyada methods yaad rakhne padte hain
- Facade baaki objects se tightly coupled hota hai → maintenance difficult
- Ye OCP violate karta hai hamesha
- Iterator ki zaroorat padti hai
Facade order/seller/package/delivery sab se coupled hai — kisi me bhi change hua toh facade bhi badalna padega. (Advantage yaad rakho: complexity isolate karke client ko simple interface dena.)
Product class ek existing ConversionCalculator library use karna chahti hai par interfaces incompatible hain aur library pe control nahi hai. Kaunsa pattern lagega?
Adapter (e.g. CostCalculatorAdapter) wrapper ki tarah client aur adaptee ke beech link banata hai — incompatibility adapter handle karta hai, client ko details pata nahi chalti. Follows SRP + OCP.
Java ke Iterator interface ke 2 key methods aur unka kaam batao.
hasNext() — true agar iteration me aur elements hain; next() — agla element return karta hai. Point: client ko
underlying data structure (ArrayList/LinkedList) se matlab nahi — access ka behaviour
alag iterator object me hai.
YouTube channel subscribe karke bell dabane pe naye video ki notification aati hai. Is scenario me subject kaun hai, observer kaun, aur kaunsa method sabko update karta hai?
Subject = channel, Observers = subscribed users.
Subject observers ki list rakhta hai (register/unregister) aur notifyObservers() list pe iterate karke har observer ka update() bulata hai — sirf subscribed logon ko hi update jaata
hai.
OrderManager me deliverFIFO() aur deliverPriority() methods hain; nayi strategy ke liye har baar naya method add karna padta hai. Pattern + fix batao.
Ye approach OCP violate karti hai. Fix: OrderDeliveryStrategy
interface (deliverOrders()) banao; FIFOOrderDelivery / PriorityOrderDelivery alag
classes me apna algorithm implement karein; context strategy object ko kaam
delegate kare. Nayi strategy = nayi class, existing code untouched.
(Con: 1-2 strategies ke liye overkill.)
05Ek-Line Cheat Sheet
| Concept | Ek line me |
|---|---|
| Software Architecture | Code organise karne ka tareeka — elements, relations, aur dono ki properties define karta hai |
| Client-Server | Request → Response (Google Search, internet) |
| Pipe & Filter | Data component-to-component transform hota hai (Compiler) |
| MVC | Model = data, View = GUI, Controller = coordinator |
| P2P | Nodes resources share karte hain, no central system |
| Component / Connector / Protocol | Functionality / info transmit karne wala code / interaction ke rules |
| Design Smell | Anti-pattern ki taraf jaane ka warning sign |
| SRP | Ek class = ek kaam (Seller → Seller + Product + Inventory) |
| OCP | Extend karo, modify mat karo (Clothing extends Product) |
| LSP | Derived class, base class se substitutable ho (email vs mobile param) |
| ISP | Client pe irrelevant interface mat thopo (physical vs online delivery) |
| DIP | Interface se couple karo, implementation se nahi (PaymentAccount) |
| Factory | new ki jagah factory method se object creation delegate (createCourier) |
| Builder | Telescoping constructors ka ilaaj — step-by-step build() |
| Facade | Complex classes ke aage simple interface (DeliveryFacade.deliver()) |
| Adapter | Incompatible interfaces ke beech wrapper (currency converter) |
| Iterator | hasNext()/next() — access ko storage se alag karo |
| Observer | Subject notify kare registered observers ko (YouTube 🔔) |
| Strategy | Algorithms alag classes me, context delegate kare (FIFO vs Priority) |