December 1, 2024

Дерево классов

Да, вы совершенно правы! Мы можем создать класс для задачи, а также предоставить более сложную структуру, в которой разные экземпляры класса задачи могут содержать различные методы и логику. Это позволит еще больше повысить модульность и гибкость программы.

### Пример реализации задачи как класса

Вот более подробный вариант, где каждую задачу можно реализовать как отдельный класс, наследующийся от базового класса `Task`. Таким образом, каждая задача может иметь свой собственный метод выполнения:

```python
class Task:
"""Базовый класс для задачи."""

def __init__(self, task_name):
self.task_name = task_name # Имя задачи

def perform_task(self):
"""Выполняет задачу. В базовом классе ничего не делает."""
raise NotImplementedError("Subclasses should implement this method.")

class SimpleTask(Task):
"""Простая задача, которая просто возвращает лог выполнения."""

def perform_task(self):
return f"Simple Task '{self.task_name}' completed."

class ComplexTask(Task):
"""Сложная задача, которая может выполнять более сложную логику."""

def perform_task(self):
# В этом примере просто добавим дополнительную логику
return f"Complex Task '{self.task_name}' completed with extra processing."

class TreeNode:
"""Класс для представления узла обобщенного дерева с уникальным ID и задачей."""

def __init__(self, node_id, value, task):
self.node_id = node_id # Уникальный идентификатор узла
self.value = value # Значение узла
self.task = task # Задача, связанная с узлом
self.children = [] # Список дочерних узлов

def add_child(self, child):
"""Добавляет дочерний узел."""
self.children.append(child)

def execute(self):
"""Выполняет задачу узла и возвращает лог."""
log = self.task.perform_task()
print(f"Executing node {self.node_id} with value: '{self.value}'. {log}")
return log

class GeneralTree:
"""Класс для представления обобщенного дерева."""

def __init__(self, root_id, root_value, root_task):
self.root = TreeNode(root_id, root_value, root_task) # Создание корневого узла

def traverse_and_execute(self, node=None):
"""Проходит по дереву в глубину и выполняет задачу для каждого узла."""
if node is None:
node = self.root

# Выполняем метод execute для текущего узла
log = node.execute()

# Рекурсивно проходим по дочерним узлам
for child in node.children:
self.traverse_and_execute(child)

def add_node(self, parent_id, node_id, value, task):
"""Добавляет узел с указанным ID, значением и задачей как дочерний узел к узлу с parent_id."""
parent_node = self.find_node(self.root, parent_id)
if parent_node:
new_node = TreeNode(node_id, value, task)
parent_node.add_child(new_node)
else:
print(f"Узел с ID {parent_id} не найден.")

def find_node(self, node, node_id):
"""Ищет узел по его ID."""
if node.node_id == node_id:
return node

for child in node.children:
found_node = self.find_node(child, node_id)
if found_node:
return found_node
return None

# Пример использования:
if __name__ == "__main__":
# Создаем задачи для узлов
root_task = ComplexTask("Initialize Root")
task_b = SimpleTask("Process Child B")
task_c = SimpleTask("Process Child C")
task_d = ComplexTask("Process Child D")
task_e = SimpleTask("Process Child E")
task_f = ComplexTask("Process Child F")
task_g = SimpleTask("Process Child G")

# Создаем обобщенное дерево
tree = GeneralTree(1, "Root", root_task)

# Динамическое добавление узлов
tree.add_node(1, 2, "Child B", task_b)
tree.add_node(1, 3, "Child C", task_c)
tree.add_node(2, 4, "Child D", task_d)
tree.add_node(2, 5, "Child E", task_e)
tree.add_node(3, 6, "Child F", task_f)
tree.add_node(3, 7, "Child G", task_g)

print("Обход дерева с выполнением задач для каждого узла:")
tree.traverse_and_execute() # Выполняем обход дерева
```

### Описание структуры кода:

1. **Класс `Task`**:
- Это базовый класс для всех задач. Метод `perform_task()` является абстрактным и должен быть реализован в подклассах.

2. **Класс `SimpleTask`**:
- Наследует от `Task` и реализует метод `perform_task()`, который просто возвращает лог о выполнении задачи.

3. **Класс `ComplexTask`**:
- Также наследует от `Task` и может добавить дополнительную логику в методе `perform_task()`.

4. **Класс `TreeNode`**:
- Сохранил свою логику и получает задачи в виде экземпляров классов `Task` или его подклассов.

5. **Класс `GeneralTree`**:
- Остался без изменений, но теперь поддерживает более сложные задачи.

### Пример работы:

При запуске приведенного кода в консоли вы получите следующий вывод:

```
Обход дерева с выполнением задач для каждого узла:
Executing node 1 with value: 'Root'. Complex Task 'Initialize Root' completed with extra processing.
Executing node 2 with value: 'Child B'. Simple Task 'Process Child B' completed.
Executing node 4 with value: 'Child D'. Complex Task 'Process Child D' completed with extra processing.
Executing node 5 with value: 'Child E'. Simple Task 'Process Child E' completed.
Executing node 3 with value: 'Child C'. Simple Task 'Process Child C' completed.
Executing node 6 with value: 'Child F'. Complex Task 'Process Child F' completed with extra processing.
Executing node 7 with value: 'Child G'. Simple Task 'Process Child G' completed.
```

### Заключение:

Теперь вы имеете модульную структуру, где каждая задача представляется классовым объектом, что позволяет легко модифицировать и расширять функциональность. Вы можете добавлять новые классы задач без изменения существующего кода узлов или дерева, что делает вашу архитектуру очень гибкой и расширяемой.