Before applying Composite, client code must check object types to call display correctly, leading to clutter. After applying Composite, both File and Directory implement the same interface, so client code calls display uniformly without type checks.
### Before: Without Composite pattern
class File:
def __init__(self, name):
self.name = name
def display(self):
print(f"File: {self.name}")
class Directory:
def __init__(self, name):
self.name = name
self.files = []
def add_file(self, file):
self.files.append(file)
def display(self):
print(f"Directory: {self.name}")
for f in self.files:
f.display()
# Client code
file1 = File("file1.txt")
dir1 = Directory("dir1")
dir1.add_file(file1)
for item in [file1, dir1]:
if isinstance(item, File):
item.display()
else:
item.display()
### After: With Composite pattern
from abc import ABC, abstractmethod
class Component(ABC):
@abstractmethod
def display(self):
pass
class File(Component):
def __init__(self, name):
self.name = name
def display(self):
print(f"File: {self.name}")
class Directory(Component):
def __init__(self, name):
self.name = name
self.children = []
def add(self, component):
self.children.append(component)
def display(self):
print(f"Directory: {self.name}")
for child in self.children:
child.display()
# Client code
file1 = File("file1.txt")
dir1 = Directory("dir1")
dir1.add(file1)
for item in [file1, dir1]:
item.display()