Мы можем думать об ООП как о моделировании поведения системы. Обратите внимание, что система не обязательно должна существовать в «реальном мире», хотя метафоры реального мира иногда могут быть полезны (например, «конвейеры», «фабрики» и т. Д.).
Если наша желаемая система слишком сложна для одновременного моделирования, мы можем разбить ее на более мелкие части и смоделировать их («проблемная область»), что может потребовать дальнейшего разрушения и так далее, пока мы не доберемся до частей, поведение которых соответствует (более или менее) для некоторого объекта встроенного языка, такого как число, строка, список и т. д.
Когда у нас есть эти простые части, мы можем объединить их вместе, чтобы описать поведение больших частей, которые мы можем объединить в еще большие части, и так далее, пока мы не сможем описать все компоненты домена, которые необходимы для целого система.
Именно на этой стадии «объединения вместе» мы могли бы написать несколько классов. Мы пишем классы, когда нет существующего объекта, который ведет себя так, как мы хотим. Например, наш домен может содержать «foos», коллекции foos, называемые «bars», и коллекции баров, называемые «bazs». Мы можем заметить, что foos достаточно просты для моделирования со строками, поэтому мы делаем это. Мы находим, что бары требуют, чтобы их содержимое подчинялось определенному ограничению, которое не соответствует ни одному из представленных Python, и в этом случае мы могли бы написать новый класс для обеспечения соблюдения этого ограничения. Возможно, у баз нет таких особенностей, поэтому мы можем просто представить их списком.
Обратите внимание, что мы могли бы написать новый класс для каждого из этих компонентов (foos, bars и bazs), но нам это не нужно, если уже есть что-то с правильным поведением. В частности, для того, чтобы класс был полезен, он должен что-то «предоставлять» (данные, методы, константы, подклассы и т. Д.), Поэтому даже если у нас много слоев пользовательских классов, мы в конечном итоге должны использовать некоторую встроенную функцию; например, если бы мы написали новый класс для foos, он, вероятно, просто содержал бы строку, так почему бы не забыть класс foo и вместо этого иметь класс bar, содержащий эти строки? Имейте в виду, что классы также являются встроенным объектом, они просто очень гибкие.
Получив нашу модель предметной области, мы можем взять некоторые конкретные экземпляры этих частей и упорядочить их в «имитацию» конкретной системы, которую мы хотим смоделировать (например, «систему машинного обучения для ...»).
Как только у нас будет это моделирование, мы сможем запустить его, и, привет, у нас есть работающая (симуляция) система машинного обучения для ... (или чего-то еще, что мы моделировали)
Теперь в вашей конкретной ситуации вы пытаетесь смоделировать поведение компонента «Извлечение возможностей». Вопрос в том, есть ли какие-либо встроенные объекты, которые ведут себя как «экстрактор возможностей», или вам нужно будет разбить его на более простые вещи? Похоже, что экстракторы объектов ведут себя очень похоже на функциональные объекты, поэтому я думаю, что вы можете использовать их в качестве модели.
При изучении такого рода концепций следует иметь в виду, что разные языки могут предоставлять разные встроенные функции и объекты (и, конечно, некоторые даже не используют терминологию, такую как «объекты»!). Следовательно, решения, которые имеют смысл на одном языке, могут быть менее полезны на другом (это может даже относиться к различным версиям одного и того же языка!).
Исторически большая часть литературы по ООП (особенно «шаблоны проектирования») была сосредоточена на Java, которая довольно сильно отличается от Python. Например, классы Java не являются объектами, до недавнего времени в Java не было функциональных объектов, в Java есть строгая проверка типов (что поощряет интерфейсы и создание подклассов), в то время как в Python поддерживается типизирование утки, в Java нет объектов-модулей, целые числа Java / поплавки / и т.д.. не являются объектами, метапрограммирование / самоанализ в Java требует «рефлексии» и так далее.
Я не пытаюсь выбрать Java (в качестве другого примера, многие теории ООП вращаются вокруг Smalltalk, который опять-таки сильно отличается от Python), я просто пытаюсь указать, что мы должны очень тщательно продумать контекст и ограничения, в которых были разработаны решения, и соответствует ли это ситуации, в которой мы находимся.
В вашем случае функциональный объект кажется хорошим выбором. Если вам интересно, почему в некоторых рекомендациях «передового опыта» не упоминаются функциональные объекты как возможное решение, возможно, это просто потому, что эти рекомендации были написаны для старых версий Java!