Skip to content

Latest commit

Β 

History

History
229 lines (175 loc) Β· 9.61 KB

File metadata and controls

229 lines (175 loc) Β· 9.61 KB

Structural Design Pattern Questions

Structural patterns explain how to assemble objects and classes into larger structures while keeping them flexible and efficient.

1. Design a Payment Gateway Adapter (Adapter Pattern)

Problem Statement

Design a payment processing system that can integrate with multiple payment gateways (Stripe, PayPal, Razorpay) through a unified interface. The system should allow adding new payment providers without changing existing code.

Why This Question?

  • Relevance: Adapter pattern is crucial for integrating third-party services. Common in payment, authentication, and API integrations.
  • Real-World: E-commerce platforms integrate with multiple payment gateways. Adapter pattern provides unified interface while hiding implementation differences.
  • Pattern: Adapter pattern allows incompatible interfaces to work together.

Design Pattern: Adapter

Adapter acts as a bridge between two incompatible interfaces. Converts interface of a class into another interface clients expect.

Key Entities

  • PaymentGateway: Target interface (what client expects)
  • StripeAdapter, PayPalAdapter, RazorpayAdapter: Adapters wrapping third-party APIs
  • PaymentService: Client using unified interface
  • StripeAPI, PayPalAPI: Existing incompatible interfaces

Approach

  1. Define PaymentGateway interface with common methods (processPayment, refund)
  2. Create adapter classes implementing PaymentGateway
  3. Each adapter wraps third-party API and translates calls
  4. Client code uses PaymentGateway interface only
  5. Support factory pattern for adapter creation

Edge Cases

  • API failures and retries
  • Different error formats from providers
  • Transaction idempotency
  • Currency conversion handling

2. Design a Notification Decorator System (Decorator Pattern)

Problem Statement

Design a notification system where you can add features (encryption, compression, retry logic) to notifications dynamically without modifying base notification classes.

Why This Question?

  • Relevance: Decorator pattern enables runtime feature addition. Common in middleware, filters, and feature toggles.
  • Real-World: Java I/O streams, Python decorators, Express.js middleware use decorator pattern.
  • Pattern: Decorator adds behavior to objects dynamically without altering structure.

Design Pattern: Decorator

Decorator attaches additional responsibilities to objects dynamically. Provides flexible alternative to subclassing for extending functionality.

Key Entities

  • Notification: Component interface
  • BaseNotification: Concrete component
  • EncryptedNotification, CompressedNotification: Concrete decorators
  • NotificationDecorator: Abstract decorator class

Approach

  1. Define Notification interface with send() method
  2. Create BaseNotification implementing core functionality
  3. Create abstract NotificationDecorator wrapping Notification
  4. Implement concrete decorators (Encrypted, Compressed, Retry)
  5. Allow decorator chaining for multiple features
  6. Decorators call wrapped object's method and add behavior

Edge Cases

  • Decorator ordering matters (encrypt then compress vs compress then encrypt)
  • Performance overhead of multiple decorators
  • Error handling in decorator chain
  • Circular decorator references

3. Design a File System (Composite Pattern)

Problem Statement

Design a file system that can represent both files and directories uniformly. Directories can contain files and other directories. Support operations like calculateSize(), search(), delete() on both.

Why This Question?

  • Relevance: Composite pattern is fundamental for tree structures. Common in UI frameworks, file systems, organizational hierarchies.
  • Real-World: Operating systems, IDEs, and UI frameworks use composite pattern extensively.
  • Pattern: Composite composes objects into tree structures to represent part-whole hierarchies.

Design Pattern: Composite

Composite lets you compose objects into tree structures. Clients treat individual objects and compositions uniformly.

Key Entities

  • FileSystemComponent: Component interface
  • File: Leaf component
  • Directory: Composite component containing children
  • FileSystem: Root of the tree structure

Approach

  1. Define FileSystemComponent interface with common operations
  2. File implements interface directly (leaf)
  3. Directory implements interface and contains list of FileSystemComponent
  4. Directory operations delegate to children
  5. Support recursive operations (size calculation, search)
  6. Handle parent-child relationships

Edge Cases

  • Circular references (directory containing itself)
  • Empty directories
  • Permission checks on operations
  • Large directory trees (performance)

4. Design an API Gateway (Facade Pattern)

Problem Statement

Design a simplified interface for a complex microservices system. The gateway should provide unified endpoints that internally coordinate multiple services (Authentication, Payment, Inventory, Shipping).

Why This Question?

  • Relevance: Facade pattern simplifies complex subsystems. Essential in microservices architecture.
  • Real-World: API Gateways (Kong, AWS API Gateway) provide unified interface to multiple backend services.
  • Pattern: Facade provides simplified interface to complex subsystem.

Design Pattern: Facade

Facade provides unified interface to set of interfaces in subsystem. Defines higher-level interface that makes subsystem easier to use.

Key Entities

  • APIGateway: Facade class
  • AuthService, PaymentService, InventoryService: Subsystem classes
  • OrderService: Orchestrates multiple services
  • Client: Uses simplified facade interface

Approach

  1. Identify complex subsystem (multiple microservices)
  2. Create APIGateway facade with simplified methods
  3. Facade coordinates calls to multiple services
  4. Handle service failures and fallbacks
  5. Implement request/response transformation
  6. Add caching and rate limiting at facade level

Edge Cases

  • Service failures and circuit breakers
  • Partial failures (some services succeed, others fail)
  • Request timeout handling
  • Service discovery and load balancing

5. Design a Caching Proxy (Proxy Pattern)

Problem Statement

Design a proxy for a database service that adds caching layer. The proxy should intercept database calls, check cache first, and only query database on cache miss.

Why This Question?

  • Relevance: Proxy pattern is fundamental for cross-cutting concerns. Common in caching, security, logging, lazy loading.
  • Real-World: Hibernate lazy loading, Spring AOP, CDN proxies use proxy pattern.
  • Pattern: Proxy provides placeholder for another object to control access.

Design Pattern: Proxy

Proxy provides surrogate or placeholder for another object to control access. Can add functionality like caching, security, lazy loading.

Key Entities

  • DatabaseService: Subject interface
  • RealDatabaseService: Real subject (actual database)
  • CachingProxy: Proxy implementing same interface
  • Cache: Storage for cached data

Approach

  1. Define DatabaseService interface
  2. Implement RealDatabaseService with actual database calls
  3. Create CachingProxy implementing same interface
  4. Proxy maintains reference to real service
  5. Intercept calls: check cache, return if found, else delegate to real service
  6. Implement cache invalidation strategies

Edge Cases

  • Cache expiration and TTL
  • Cache invalidation on updates
  • Memory management for cache
  • Cache stampede (thundering herd)

6. Design a UI Component System (Bridge Pattern)

Problem Statement

Design a UI rendering system that can work with different rendering engines (Web, Mobile, Desktop) and different UI themes (Light, Dark). The system should allow adding new engines or themes independently.

Why This Question?

  • Relevance: Bridge pattern decouples abstraction from implementation. Common in cross-platform frameworks.
  • Real-World: React Native, Flutter use bridge pattern to abstract platform differences.
  • Pattern: Bridge separates abstraction from implementation so both can vary independently.

Design Pattern: Bridge

Bridge decouples abstraction from implementation so both can vary independently. Useful when you want to avoid permanent binding between abstraction and implementation.

Key Entities

  • UIComponent: Abstraction interface
  • Button, TextField: Concrete abstractions
  • RenderingEngine: Implementation interface
  • WebRenderer, MobileRenderer: Concrete implementations
  • Theme: Additional dimension (Light, Dark)

Approach

  1. Separate abstraction (UI components) from implementation (rendering)
  2. Define RenderingEngine interface
  3. Create concrete renderers for each platform
  4. UI components contain reference to renderer
  5. Components delegate rendering to engine
  6. Support theme variations through composition

Edge Cases

  • Platform-specific limitations
  • Theme switching at runtime
  • Performance across platforms
  • Accessibility features per platform

πŸ“ Practice Tips

  1. Understand Relationships: Structural patterns are about relationships between objects
  2. Composition over Inheritance: Most structural patterns favor composition
  3. Interface Design: Focus on clean, minimal interfaces
  4. Performance: Consider overhead of additional layers
  5. Real-World Mapping: Relate patterns to libraries/frameworks you've used

πŸ”— Related Resources