Structural Patterns • Proxy PatternMedium⏱️ ~3 min
Proxy Pattern: Library Book Management Application
Consider a digital library system where books can be downloaded. Some books are large (500MB+ technical manuals with embedded videos) and should only be loaded when a user actually opens them, not when browsing the library catalog. Additionally, premium books require subscription verification before access.
Design with Virtual and Protection Proxy:
«interface»
BookContent
+ getMetadata(): Metadata
+ readChapter(num): String
+ download(): ByteArray
+ readChapter(num): String
+ download(): ByteArray
RealBook
- fileData: ByteArray
- chapters: List<Chapter>
- chapters: List<Chapter>
+ getMetadata(): Metadata
+ readChapter(num): String
+ download(): ByteArray
+ readChapter(num): String
+ download(): ByteArray
BookProxy
- realBook: RealBook
- metadata: Metadata
- isLoaded: Boolean
- user: User
- metadata: Metadata
- isLoaded: Boolean
- user: User
+ getMetadata(): Metadata
+ readChapter(num): String
+ download(): ByteArray
- checkAccess(): Boolean
- ensureLoaded(): void
+ readChapter(num): String
+ download(): ByteArray
- checkAccess(): Boolean
- ensureLoaded(): void
▲ Both implement BookContent | ◆ Proxy lazily creates RealBook
Method Implementations:
BookProxy.getMetadata():
// Metadata is lightweight, return immediately without loading full book
return this.metadata
BookProxy.readChapter(num):
if not checkAccess():
throw AccessDeniedException("Premium subscription required")
ensureLoaded() // Lazy load: create RealBook only when first accessed
return realBook.readChapter(num)
BookProxy.ensureLoaded():
if not isLoaded:
realBook = new RealBook(metadata.filePath) // Expensive: loads 500MB file
isLoaded = true
BookProxy.checkAccess():
if metadata.isPremium:
return user.hasActiveSubscription()
return true
// Metadata is lightweight, return immediately without loading full book
return this.metadata
BookProxy.readChapter(num):
if not checkAccess():
throw AccessDeniedException("Premium subscription required")
ensureLoaded() // Lazy load: create RealBook only when first accessed
return realBook.readChapter(num)
BookProxy.ensureLoaded():
if not isLoaded:
realBook = new RealBook(metadata.filePath) // Expensive: loads 500MB file
isLoaded = true
BookProxy.checkAccess():
if metadata.isPremium:
return user.hasActiveSubscription()
return true
Benefits in This Context:
- Performance: Library catalog loads instantly showing 10,000 books. Each BookProxy holds only metadata (title, author, cover thumbnail). The actual 500MB book files are loaded only when a user opens a book.
- Security: Access control logic is centralized in the Proxy. RealBook does not need to know about subscription tiers, user authentication, or business rules. It focuses purely on content delivery.
- Consistency: All books (free and premium) use the same BookContent interface. The UI layer treats all books uniformly without conditional logic for access checking.
Interview Tip: When presenting this example, walk through the state transitions: initial catalog load (Proxy with metadata only), user clicks book (access check), first chapter request (lazy load triggers), subsequent chapter requests (uses cached RealBook). This demonstrates understanding beyond static structure.
💡 Key Takeaways
✓Virtual Proxy delays loading 500MB book files until actually needed
✓Protection Proxy checks subscription status before allowing premium content access
✓Lightweight metadata (title, author) stored in Proxy for fast catalog browsing
✓RealBook is created only once per Proxy when first content access occurs
✓Single BookContent interface used throughout UI, hiding proxy complexity
📌 Examples
1Catalog displays 10,000 BookProxy objects with metadata only
2User opens premium book: Proxy checks subscription before creating RealBook
3User switches chapters: Proxy reuses already-loaded RealBook instance
4Free book access: Proxy skips subscription check and loads content immediately