Structural Patterns • Composite PatternMedium⏱️ ~3 min
Applying Composite to a Document Editor
Let's design a document editor where text can be formatted in groups. Individual characters and groups of characters (paragraphs, sections) should support the same operations like render() and getCharCount().
«interface»
DocumentElement
+ render(): String
+ getCharCount(): int
+ add(DocumentElement): void
+ remove(DocumentElement): void
▲
Character
- value: char
+ render(): String
+ getCharCount(): int
CompositeElement
- children: List<DocumentElement>
+ render(): String
+ getCharCount(): int
+ add(DocumentElement): void
▲
Paragraph
+ render(): String
Section
+ render(): String
Implementation Pseudocode:
class Character implements DocumentElement:
value: char
render():
return value.toString()
getCharCount():
return 1
add(element):
throw UnsupportedOperationException("Cannot add to leaf")
class Paragraph extends CompositeElement:
render():
result = ""
for each child in children:
result += child.render()
result += "
"
return result
class Section extends CompositeElement:
render():
result = ""
for each child in children:
result += child.render()
result += " "
return result
class CompositeElement implements DocumentElement:
children: List
getCharCount():
total = 0
for each child in children:
total += child.getCharCount()
return total
add(element):
children.add(element)
remove(element):
children.remove(element) Interview Tip: When explaining your design, emphasize the uniformity. A client can call
getCharCount() on a single Character (returns 1) or an entire Section containing multiple Paragraphs (returns sum of all descendants) using identical code.Usage Example: Building a document structure looks like this:
section = new Section()
paragraph1 = new Paragraph()
paragraph1.add(new Character('H'))
paragraph1.add(new Character('i'))
section.add(paragraph1)
totalChars = section.getCharCount() // Returns 2
html = section.render() // Returns "Hi
"💡 Key Takeaways
✓Document editor treats characters and text groups uniformly
✓Character is leaf with no children, implements operations directly
✓CompositeElement handles child management and delegates operations
✓Paragraph and Section extend CompositeElement with specific rendering
✓Client code works identically whether operating on leaf or composite
📌 Examples
1section.getCharCount() works on entire hierarchy
2paragraph.render() recursively renders all child characters
3Adding new composite types (Table, List) requires no client changes