Python

"-"

  • """"""

"-"


1. (Component)

from abc import ABC, abstractmethod
from typing import List

class FileSystemComponent(ABC):
    """"""
   
    def __init__(self, name: str):
        self.name = name
        self.parent = None
   
    @abstractmethod
    def display(self, indent: int = 0) -> None:
        """"""
        pass
   
    @abstractmethod
    def get_size(self) -> int:
        """"""
        pass
   
    def get_path(self) -> str:
        """"""
        if self.parent:
            return f"{self.parent.get_path()}/{self.name}"
        return self.name

2. (Leaf)

class File(FileSystemComponent):
    """ - """
   
    def __init__(self, name: str, size: int):
        super().__init__(name)
        self._size = size
   
    def display(self, indent: int = 0) -> None:
        """"""
        spaces = "  " * indent
        print(f"{spaces}📄 {self.name} ({self._size} bytes)")
   
    def get_size(self) -> int:
        """"""
        return self._size

3. (Composite)

class Directory(FileSystemComponent):
    """ - """
   
    def __init__(self, name: str):
        super().__init__(name)
        self._children: List[FileSystemComponent] = []
   
    def add(self, component: FileSystemComponent) -> None:
        """"""
        component.parent = self
        self._children.append(component)
   
    def remove(self, component: FileSystemComponent) -> None:
        """"""
        self._children.remove(component)
        component.parent = None
   
    def display(self, indent: int = 0) -> None:
        """"""
        spaces = "  " * indent
        print(f"{spaces}📁 {self.name}/")
       
        #
        for child in self._children:
            child.display(indent + 1)
   
    def get_size(self) -> int:
        """"""
        total_size = 0
        for child in self._children:
            total_size += child.get_size()
        return total_size
   
    def find_component(self, name: str) -> FileSystemComponent:
        """"""
        for child in self._children:
            if child.name == name:
                return child
            if isinstance(child, Directory):
                found = child.find_component(name)
                if found:
                    return found
        return None

def demonstrate_composite_pattern():
    """"""
   
    #
    root = Directory("root")
   
    #
    documents = Directory("documents")
    pictures = Directory("pictures")
    music = Directory("music")
   
    #
    readme = File("README.txt", 1024)
    notes = File("notes.md", 2048)
    photo1 = File("vacation.jpg", 1536000)
    photo2 = File("family.png", 2048000)
    song1 = File("song1.mp3", 4096000)
    song2 = File("song2.mp3", 5120000)
   
    #
    root.add(readme)
    root.add(documents)
    root.add(pictures)
    root.add(music)
   
    documents.add(notes)
   
    pictures.add(photo1)
    pictures.add(photo2)
   
    music.add(song1)
    music.add(song2)
   
    #
    print("=== ===")
    root.display()
   
    print("\n=== ===")
    print(f": {root.get_size()} bytes")
    print(f": {pictures.get_size()} bytes")
    print(f": {music.get_size()} bytes")
   
    print("\n=== ===")
    print(f": {photo1.get_path()}")
    print(f": {pictures.get_path()}")
   
    print("\n=== ===")
    found = root.find_component("song1.mp3")
    if found:
        print(f": {found.get_path()}")

#
if __name__ == "__main__":
    demonstrate_composite_pattern()

34956fd2-0e5f-4b91-82f2-5b72e3e4953f.png [34956fd2-0e5f-4b91-82f2-5b72e3e4953f.png]


UML

python-composite.png [python-composite.png]



1. GUI

class UIComponent:
    """UI """
    def render(self):
        pass
    def add(self, component):
        pass

class Button(UIComponent):
    """ - """
    def render(self):
        print("")

class Panel(UIComponent):
    """ - """
    def __init__(self):
        self.children = []
   
    def add(self, component):
        self.children.append(component)
   
    def render(self):
        print("")
        for child in self.children:
            child.render()
        print("")

2.

class Employee:
    """"""
    def get_salary(self):
        pass

class Developer(Employee):
    """ - """
    def __init__(self, salary):
        self.salary = salary
   
    def get_salary(self):
        return self.salary

class Department(Employee):
    """ - """
    def __init__(self):
        self.employees = []
   
    def add(self, employee):
        self.employees.append(employee)
   
    def get_salary(self):
        return sum(emp.get_salary() for emp in self.employees)

1

2

3


GUI