Composite: treat a tree uniformly
Picture
A file has a size. A folder’s size is the sum of its children, which may themselves be folders.
Predict
What happens if a folder contains itself in this simple recursive design?
Walk through the small example
The tree assumption breaks. Cycles need detection or a different graph-aware contract.
Mental model and complete Python solution
Leaf and Folder share a size operation. Folder recursively combines child answers, directly connecting composite design to tree summaries. Ownership rules must prohibit cycles for this simple model. A real file system has hard links and symbolic links; counting physical storage versus logical tree size requires different semantics.
What the function promises: The object structure is a finite acyclic tree. Each File size is a nonnegative integer. Folder children are snapshotted as a tuple.
class File:
def __init__(self, bytes_count):
if type(bytes_count) is not int or bytes_count < 0:
raise ValueError("Invalid size")
self.bytes_count = bytes_count
def size(self):
return self.bytes_count
class Folder:
def __init__(self, children):
self.children = tuple(children)
def size(self):
return sum(child.size() for child in self.children)
tree = Folder([File(3), Folder([File(4), File(5)])])
assert tree.size() == 12
assert Folder([]).size() == 0
Work and storage: O(number of visited objects) time and O(tree height) recursion depth. Very deep structures may require an explicit stack.
When to recognize it: Composite makes leaves and groups usable through one operation. The input must obey the promised tree structure.
Check before applying it: Composite assumes a valid containment model; shared nodes and cycles change traversal semantics.
Change one rule
The same File object appears in two folders. Should its bytes be counted twice?
See what changes
That depends on the requested view. Logical entry size may count twice; unique physical storage needs identity-based deduplication. State the ownership and accounting contract.
Connect
tree summaries: Reuse the same child-summary recursion as a tree algorithm.
Visitor: add operations over stable types: Add new operations over a stable family of tree elements.