Декомпозиция — это разбиение крупной задачи на более простые, управляемые подзадачи или функции. Исторически декомпозиция возникла как ключевой принцип модульного программирования: она упрощает управление сложностью, тестируемость и повторное использование кода.
Проблема: Без декомпозиции код становится "монолитом": его сложно читать, поддерживать и изменять, сложнее писать тесты и переиспользовать части программы.
Решение: В Python декомпозиция реализуется: разбивкой логики на функции, классы, модули; четким именованием; использованием композиции и абстракций. Это позволяет писать читаемый и масштабируемый код.
Пример кода:
# Некомпактный монолитный код numbers = [1, 2, 3, 4] squares = [] for n in numbers: if n % 2 == 0: squares.append(n**2) print(squares) # Декомпозированный вариант def is_even(n): return n % 2 == 0 def square(n): return n ** 2 def filter_and_apply(numbers, predicate, func): return [func(n) for n in numbers if predicate(n)] numbers = [1, 2, 3, 4] result = filter_and_apply(numbers, is_even, square) print(result)
Ключевые особенности:
Может ли одна функция реализовывать всю бизнес-логику, если она небольшая?
Часто считают, что если задача мало весит, разрешается писать "функцию на 100 строк". Это анти-паттерн: даже небольшая задача усложняется при малейших изменениях; микрофункции гораздо проще тестировать и поддерживать.
Могут ли функции с одинаковой логикой но разными именами рассматриваться как декомпозиция?
Нет, дублирование кода — плохая декомпозиция. Повторяющийся код говорит о неверно выбранных границах подзадач. Надо всегда выносить повторяющуюся функциональность во вспомогательные функции.
Пример:
def add_user(): pass # логика def add_admin(): pass # та же логика, что выше!
Нужно ли декомпозировать вспомогательные задачи, если они используются только в одном месте?
Да, зачастую такие функции помогут сделать код проще даже при единичном использовании (например, выделять условия или фильтрацию в отдельную функцию).
Проект с обработкой данных поступал через одну огромную функцию на 300 строк. Каждый баг вызывал панику: невозможно быстро понять, что и где случилось, тестирование практически невозможно.
Плюсы:
Минусы:
Тот же проект, рефакторинг — код разбит на небольшие функции и классы по основной логике (чтение, валидация, обработка, запись данных).
Плюсы:
Минусы: