Covers main structural patterns like Adapter, Bridge, Composite, Decorator, Facade, Flyweight, Proxy. Does not cover behavioral or creational patterns.
Functional Requirements
FR1: Explain common structural design patterns
FR2: Describe scenarios when each pattern is appropriate
FR3: Provide simple examples of use cases
FR4: Highlight benefits and trade-offs of each pattern
Non-Functional Requirements
NFR1: Use clear, simple language without jargon
NFR2: Focus on practical, real-world applicability
NFR3: Keep explanations beginner-friendly
NFR4: Avoid overly complex or theoretical details
Think Before You Design
Questions to Ask
❓ Question 1
❓ Question 2
❓ Question 3
❓ Question 4
Key Components
Client code using the pattern
Interfaces or abstract classes involved
Concrete implementations or wrappers
Relationships between objects (composition, inheritance)
Convert interface of one class to another expected by client
Bridge
Any OOP language
Separate abstraction from implementation to vary independently
Composite
Any OOP language
Compose objects into tree structures to represent part-whole hierarchies
Decorator
Any OOP language
Add responsibilities to objects dynamically without subclassing
Facade
Any OOP language
Provide a simple interface to a complex subsystem
Flyweight
Any OOP language
Share common parts of objects to save memory
Proxy
Any OOP language
Control access to another object, add extra functionality
Request Flow
1. Client calls Adapter to use incompatible interface as expected.
2. Bridge separates abstraction and implementation; client uses abstraction.
3. Composite allows client to treat individual and composite objects uniformly.
4. Decorator wraps object to add features without changing original code.
5. Facade simplifies client interaction by hiding subsystem complexity.
6. Flyweight shares common data among many objects to reduce memory use.
7. Proxy controls access to real object, adding security or lazy loading.
Database Schema
Not applicable for structural patterns; focus is on object relationships and code structure.
Scaling Discussion
Bottlenecks
Adapter can add overhead if many conversions are chained.
Bridge may increase complexity if abstraction and implementation grow independently.
Composite trees can become large and slow to traverse.
Decorator layers can cause deep wrapping and debugging difficulty.
Facade may hide too much, limiting flexibility.
Flyweight requires careful management of shared state to avoid errors.
Proxy can introduce latency or bottlenecks if overused.
Solutions
Keep Adapter usage minimal and well-defined.
Maintain clear separation and documentation in Bridge pattern.
Optimize Composite tree traversal and caching results.
Limit Decorator layers and use clear naming conventions.
Design Facade to balance simplicity and access to features.
Manage Flyweight shared data carefully with immutability where possible.
Use Proxy selectively and monitor performance impact.
Interview Tips
Time: Spend 10 minutes explaining each pattern briefly, 15 minutes discussing use cases and trade-offs, 10 minutes answering questions.
Explain problem each pattern solves with simple examples.
Describe when to choose one pattern over another.
Discuss benefits like flexibility, maintainability, and reuse.
Mention potential downsides and how to mitigate them.
Show understanding of object relationships and design goals.
Practice
(1/5)
1. Which structural pattern is best suited for representing part-whole hierarchies like folders and files in a system?
easy
A. Facade pattern
B. Composite pattern
C. Proxy pattern
D. Decorator pattern
Solution
Step 1: Understand the problem context
Part-whole hierarchies like folders and files form tree structures where each node can be a composite or a leaf.
Step 2: Match the pattern to the structure
The Composite pattern is designed to treat individual objects and compositions uniformly, perfect for tree-like structures.
Final Answer:
Composite pattern -> Option B
Quick Check:
Tree structures = Composite pattern [OK]
Hint: Tree or hierarchy? Use Composite pattern [OK]
Common Mistakes:
Confusing Decorator with Composite
Using Proxy for hierarchy management
Choosing Facade for internal structure
2. Which pattern should you use if you want to add responsibilities to objects dynamically without changing their class?
easy
A. Proxy pattern
B. Facade pattern
C. Composite pattern
D. Decorator pattern
Solution
Step 1: Identify the need to add features dynamically
When you want to add new behavior to objects at runtime without altering their class, you need a flexible pattern.
Step 2: Select the pattern that wraps objects
The Decorator pattern wraps objects to add responsibilities dynamically, without changing the original class.
Final Answer:
Decorator pattern -> Option D
Quick Check:
Add features dynamically = Decorator [OK]
Hint: Add features on the fly? Use Decorator [OK]
Common Mistakes:
Choosing Proxy instead of Decorator
Using Facade to add features
Confusing Composite with Decorator
3. Consider a system where you want to control access to a resource and add lazy loading. Which structural pattern fits best?
class ResourceProxy {
constructor() {
this.resource = null;
}
access() {
if (!this.resource) {
this.resource = new RealResource();
}
return this.resource;
}
}
medium
A. Proxy pattern
B. Decorator pattern
C. Composite pattern
D. Facade pattern
Solution
Step 1: Analyze the code behavior
The code delays creating the real resource until it is accessed, controlling access and adding lazy loading.
Step 2: Identify the matching pattern
This behavior matches the Proxy pattern, which controls access to another object and can add lazy initialization.
Final Answer:
Proxy pattern -> Option A
Quick Check:
Control access + lazy load = Proxy [OK]
Hint: Control access or lazy load? Use Proxy [OK]
Common Mistakes:
Confusing Proxy with Decorator
Using Facade for access control
Choosing Composite for resource control
4. You have a complex subsystem with many classes. You want to provide a simple interface to clients. Which pattern should you use?
A developer wrote this code but clients still see complex calls:
class ComplexSystem {
operationA() {}
operationB() {}
operationC() {}
}
class SimpleInterface {
constructor() {
this.system = new ComplexSystem();
}
simpleOperation() {
this.system.operationA();
this.system.operationB();
this.system.operationC();
}
}
What is the likely mistake?
medium
A. They did not hide the ComplexSystem instance properly
B. They used Proxy instead of Facade
C. They used Composite instead of Facade
D. They forgot to add Decorator to SimpleInterface
Solution
Step 1: Understand Facade pattern purpose
Facade provides a simple interface hiding complex subsystem details from clients.
Step 2: Identify the mistake in code usage
If clients still see complex calls, likely the ComplexSystem instance is exposed or clients bypass the Facade.
Final Answer:
They did not hide the ComplexSystem instance properly -> Option A
5. You are designing a graphic editor. You want to represent shapes that can be simple (circle, square) or groups of shapes. You also want to add features like border color dynamically and control access to some shapes. Which combination of structural patterns should you use?
hard
A. Facade for groups, Proxy for features, Composite for access control
B. Decorator for groups, Composite for features, Facade for access control
C. Composite for groups, Decorator for features, Proxy for access control
D. Proxy for groups, Facade for features, Decorator for access control
Solution
Step 1: Match patterns to requirements
Groups of shapes form tree structures best handled by Composite. Adding features dynamically fits Decorator. Controlling access fits Proxy.
Step 2: Combine patterns correctly
Use Composite for shape groups, Decorator to add border color dynamically, and Proxy to control access to shapes.
Final Answer:
Composite for groups, Decorator for features, Proxy for access control -> Option C