2.2.11 · HinglishDesign Principles

Design Patterns — Structural - Adapter, Bridge, Composite, Decorator, Facade, Flyweight, Proxy

2,347 words11 min readRead in English

2.2.11 · Coding › Design Principles

Saat classic structural patterns (GoF) do intentions mein clearly split hote hain:

Intention Patterns
Incompatible / unrelated cheezein ek saath kaam karwaana Adapter, Bridge, Facade
Object trees aur capabilities build / extend karna Composite, Decorator, Proxy, Flyweight
Figure — Design Patterns — Structural -  Adapter, Bridge, Composite, Decorator, Facade, Flyweight, Proxy

The 80/20: jo actually matter karta hai


1. Adapter — ek interface translate karo

WHY: Tumhare paas ek working class hai (third-party library, legacy code) lekin uske method names/signatures waise nahi hain jaise tumhara code call karta hai. Tum use edit nahi kar sakte (ya nahi karna chahiye).

WHAT: Ek wrapper jo target interface expose karta hai, andar se adaptee ko call karta hai.

HOW (derive from scratch):

# Client wants this interface:
class MediaPlayer:           # Target
    def play(self, file): ...
 
# But we already have this incompatible class:
class LegacyMp4(object):     # Adaptee
    def start_mp4(self, path):
        print("playing", path)
 
# Bridge the gap by FORWARDING with a translated name:
class Mp4Adapter(MediaPlayer):
    def __init__(self, legacy):
        self._legacy = legacy        # composition: hold the adaptee
    def play(self, file):
        self._legacy.start_mp4(file) # translate play() -> start_mp4()

Ye step kyun? Mp4Adapter wo interface implement karta hai jo client bolta hai (play), toh client ko kabhi pata nahi chalta ki koi legacy class exist karti hai.


2. Bridge — abstraction ko implementation se alag karo

HOW:

class Color:                      # Implementation side
    def fill(self): ...
class Red(Color):
    def fill(self): return "red"
 
class Shape:                      # Abstraction side
    def __init__(self, color):    # holds a reference -> the "bridge"
        self.color = color
    def draw(self): ...
class Circle(Shape):
    def draw(self):
        return "Circle in " + self.color.fill()

Ye step kyun? Shape has-a Color (composition) instead of ek coloured shape being (inheritance). Naya colour add karo → ek class; nayi shape add karo → ek class.


3. Composite — ek aur bahut ko same treat karo

WHY: Files & folders, GUI panels jo widgets contain karte hain, org charts — recursive part-whole hierarchies jahan tum chahte ho ki render() ya size() kaam kare chahe leaf par call karo ya poore subtree par.

HOW:

class Node:
    def size(self): raise NotImplementedError
class File(Node):                 # Leaf
    def __init__(self, kb): self.kb = kb
    def size(self): return self.kb
class Folder(Node):               # Composite
    def __init__(self): self.children = []
    def add(self, n): self.children.append(n)
    def size(self):
        return sum(c.size() for c in self.children)  # recurse uniformly

Ye step kyun? Folder.size() har child par size() call karta hai type check kiye bina — recursion aur uniform interface hi poora point hai.


4. Decorator — wrap karke behaviour add karo

HOW:

class Coffee:                     # Component
    def cost(self): return 2.0
class AddOn(Coffee):              # Decorator base: wraps a Coffee, IS a Coffee
    def __init__(self, drink): self.drink = drink
class Milk(AddOn):
    def cost(self): return self.drink.cost() + 0.5   # forward + add
class Sugar(AddOn):
    def cost(self): return self.drink.cost() + 0.2
 
order = Sugar(Milk(Coffee()))     # stackable: 2.0 + 0.5 + 0.2 = 2.7

Ye step kyun? Milk.cost() pehle wrapped object ko call karta hai, phir apna hissa add karta hai — wo "call inner, then extend" hi decorators ko composable banata hai.


5. Facade — ek complex subsystem ka simple darwaza

WHY: Computer start karna matlab CPU, Memory, Disk sab milkar kaam karte hain. Client bas start() chahta hai.

HOW:

class Facade:
    def __init__(self): self.cpu, self.mem, self.disk = CPU(), Mem(), Disk()
    def start(self):
        self.cpu.freeze(); self.mem.load(); self.disk.read(); self.cpu.jump()

Ye step kyun? Facade subsystem ko orchestrate karta hai taaki client char ordered calls ki jagah ek call kare. Note: Facade subsystem ko hide nahi karta — advanced clients seedha reach bhi kar sakte hain.


6. Flyweight — share karke memory bachao

HOW:

class GlyphFactory:
    _pool = {}
    def get(self, char):
        if char not in self._pool:
            self._pool[char] = Glyph(char)   # create once, reuse forever
        return self._pool[char]              # SHARED instance
# extrinsic state (x,y) passed at draw time, not stored in Glyph

Ye step kyun? Factory intrinsic key se cache karta hai taaki repeated requests same object return karein — wo sharing hi memory win hai.


7. Proxy — ek stand-in jo access control kare

HOW:

class RealImage:
    def __init__(self, f): self._load(f)      # expensive!
    def display(self): ...
class ProxyImage:
    def __init__(self, f): self.f, self.real = f, None
    def display(self):
        if self.real is None:                 # lazy: load only on first use
            self.real = RealImage(self.f)
        self.real.display()

Ye step kyun? Proxy expensive construction ko defer karta hai jab tak display() actually call nahi hota — same interface, controlled access.



Recall Feynman: 12-year-old ko explain karo

LEGO imagine karo. Adapter ek chota brick hai jo do LEGO sets ko connect karta hai jo normally click nahi karte. Decorator ek car par stickers aur lights lagana hai — har ek kuch add karta hai, aur tum add karte reh sakte ho. Composite LEGO ka ek box hai jise tum ek cheez ki tarah carry kar sakte ho, chahe andar chote pieces hon, aur boxes mein boxes bhi ho sakten hain. Facade ek bada laal "GO" button hai jo secretly tumhare liye das steps karta hai. Proxy ek guard hai jo ek treasure room ke saamne khada hai aur door tab hi kholta hai jab tum sach mein allowed ho. Flyweight ek video game mein hazaar baar ek hi tree ki picture use karna hai instead of hazaar trees draw karne ke. Bridge "shape" aur "colour" ko do alag sticker sheets mein rakhna hai taaki tum koi bhi shape kisi bhi colour ke saath mix kar sako bina har combo by hand banaye.


Flashcards

Adapter kaunsi problem solve karta hai?
Do interfaces incompatible hain; adapter ek ko doosre mein translate karta hai taaki dono saath kaam kar sakein.
Adapter vs Bridge — core difference kya hai?
Adapter ek existing mismatch ko baad mein fix karta hai; Bridge pehle se design hota hai taaki abstraction & implementation independently vary kar sakein (class explosion avoid karne ke liye).
Bridge class explosion kyun reduce karta hai?
Ye combinations (inheritance) ko classes (composition) mein badal deta hai abstraction ko implementation ka reference deke.
Key property jo Decorators ko stack karne deti hai?
Ek decorator wahi same interface implement karta hai jo wo wrap karta hai, isliye wo interchangeable hai aur dobara wrap ho sakta hai.
Decorator vs Proxy — intent?
Decorator responsibilities add karta hai; Proxy access control karta hai (lazy load, permission, cache, remote).
Composite ko powerful kya banata hai?
Leaf aur group ek interface share karte hain, toh clients single objects aur poore trees ko recursion ke zariye uniformly treat karte hain.
Kya Facade subsystem ko completely hide karta hai?
Nahi — ye common use ke liye access simplify karta hai, lekin clients zaroorat padne par seedha subsystem tak pahunch sakte hain.
Flyweight: intrinsic vs extrinsic state?
Intrinsic = shared, unchanging part jo shared object mein store hota hai; extrinsic = context-specific part jo bahar se pass in hota hai.
Chaar common Proxy types kya hain?
Virtual (lazy load), Protection (access control), Caching, Remote.
Ek sentence jo sabse zyada structural patterns ko unify karta hai?
Ek object doosre object ka reference rakhta hai aur calls forward karta hai; patterns intent se alag hote hain (translate / extend / control / share / orchestrate).

Connections

  • Composition over Inheritance — Adapter, Bridge, Decorator, Proxy ke peeche ka principle
  • Open-Closed Principle — Decorator & Bridge code modify kiye bina behaviour extend karte hain
  • Single Responsibility Principle — Facade orchestration logic isolate karta hai
  • Creational Patterns — Flyweight shared objects pool karne ke liye Factory par rely karta hai
  • Behavioral Patterns — Composite aksar Visitor / Iterator ke saath tree par pair hota hai
  • Dependency Inversion — Bridge implementation interface par depend karta hai, concretes par nahi
  • Recursion — Composite ka uniform size()/render() recursive descent hai

Concept Map

translate interface

add behaviour, same interface

control access

one call to many subsystems

forward to children tree

two hierarchies

share heavy state

stackable wrappers

make incompatible things fit

Composition forwards calls

Adapter

Decorator

Proxy

Facade

Composite

Bridge

Flyweight