Chúng ta có thể nghĩ về OOP như mô hình hóa hành vi của một hệ thống. Lưu ý rằng hệ thống không phải tồn tại trong 'thế giới thực', mặc dù các phép ẩn dụ trong thế giới thực đôi khi có thể hữu ích (ví dụ: "đường ống", "nhà máy", v.v.).
Nếu hệ thống mong muốn của chúng ta quá phức tạp để mô hình hóa tất cả cùng một lúc, chúng ta có thể chia nó thành các phần nhỏ hơn và mô hình hóa chúng ("miền vấn đề"), có thể liên quan đến việc phá vỡ thêm, và cứ thế cho đến khi chúng ta có được những mảnh ghép có hành vi phù hợp (nhiều hơn hoặc ít hơn) của một số đối tượng ngôn ngữ tích hợp như số, chuỗi, danh sách, v.v.
Khi chúng ta có những mảnh đơn giản đó, chúng ta có thể kết hợp chúng lại với nhau để mô tả hành vi của các mảnh lớn hơn, chúng ta có thể kết hợp với nhau thành các mảnh lớn hơn, và cứ như vậy cho đến khi chúng ta có thể mô tả tất cả các thành phần của miền cần thiết cho toàn bộ hệ thống.
Đây là giai đoạn "kết hợp với nhau" nơi chúng ta có thể viết một số lớp. Chúng ta viết các lớp khi không có một đối tượng hiện hành theo cách chúng ta muốn. Ví dụ: tên miền của chúng tôi có thể chứa "foos", bộ sưu tập các foos được gọi là "bar" và bộ sưu tập các thanh được gọi là "bazs". Chúng tôi có thể nhận thấy rằng foos đủ đơn giản để mô hình với các chuỗi, vì vậy chúng tôi làm điều đó. Chúng tôi thấy rằng các thanh yêu cầu nội dung của chúng phải tuân theo một số ràng buộc cụ thể không khớp với bất cứ điều gì Python cung cấp, trong trường hợp đó chúng tôi có thể viết một lớp mới để thực thi ràng buộc này. Có lẽ bazs không có đặc thù như vậy, vì vậy chúng tôi chỉ có thể đại diện cho họ với một danh sách.
Lưu ý rằng chúng ta có thể viết một lớp mới cho mỗi một trong các thành phần đó (foos, bar và bazs), nhưng chúng ta không cần phải có một cái gì đó có hành vi đúng. Đặc biệt, để một lớp trở nên hữu ích, nó cần phải 'cung cấp' thứ gì đó (dữ liệu, phương thức, hằng, lớp con, v.v.), vì vậy ngay cả khi chúng ta có nhiều lớp lớp tùy chỉnh, cuối cùng chúng ta cũng phải sử dụng một số tính năng tích hợp; ví dụ, nếu chúng ta đã viết một lớp mới cho foos thì có lẽ nó chỉ chứa một chuỗi, vậy tại sao bạn không quên lớp foo và thay vào đó là lớp bar chứa các chuỗi đó? Hãy nhớ rằng các lớp cũng là một đối tượng tích hợp, chúng chỉ là một đối tượng đặc biệt linh hoạt.
Khi chúng tôi có mô hình miền của mình, chúng tôi có thể lấy một số trường hợp cụ thể của các phần đó và sắp xếp chúng thành một "mô phỏng" của hệ thống cụ thể mà chúng tôi muốn mô hình hóa (ví dụ: "hệ thống máy học cho ...").
Khi chúng tôi có mô phỏng này, chúng tôi có thể chạy nó và xin chào, chúng tôi có một hệ thống học máy (mô phỏng) hoạt động cho ... (hoặc bất cứ điều gì khác mà chúng tôi đang tạo mô hình).
Bây giờ, trong tình huống cụ thể của bạn, bạn đang cố gắng mô hình hóa hành vi của thành phần "trình trích xuất tính năng". Câu hỏi là, có bất kỳ đối tượng tích hợp nào hoạt động như một "trình trích xuất tính năng", hoặc bạn sẽ cần phải chia nó thành những điều đơn giản hơn? Có vẻ như các trình trích xuất tính năng hoạt động rất giống các đối tượng hàm, vì vậy tôi nghĩ rằng bạn sẽ ổn khi sử dụng chúng làm mô hình của mình.
Một điều cần lưu ý khi tìm hiểu về các loại khái niệm này là các ngôn ngữ khác nhau có thể cung cấp các tính năng và đối tượng tích hợp khác nhau (và tất nhiên, một số thậm chí không sử dụng thuật ngữ như "đối tượng"!). Do đó, các giải pháp có ý nghĩa trong một ngôn ngữ có thể ít hữu ích hơn trong một ngôn ngữ khác (điều này thậm chí có thể áp dụng cho các phiên bản khác nhau của cùng một ngôn ngữ!).
Trong lịch sử, rất nhiều tài liệu OOP (đặc biệt là "các mẫu thiết kế") đã tập trung vào Java, khá khác với Python. Ví dụ, các lớp Java không phải là các đối tượng, Java không có các đối tượng hàm cho đến gần đây, Java có kiểm tra kiểu nghiêm ngặt (khuyến khích các giao diện và phân lớp) trong khi Python khuyến khích gõ vịt, Java không có các đối tượng mô đun, số nguyên Java / phao / v.v. không phải là các đối tượng, lập trình meta / hướng nội trong Java yêu cầu "phản chiếu", v.v.
Tôi không cố gắng chọn Java (như một ví dụ khác, rất nhiều lý thuyết OOP xoay quanh Smalltalk, một lần nữa rất khác với Python), tôi chỉ cố gắng chỉ ra rằng chúng ta phải suy nghĩ rất kỹ về bối cảnh và những hạn chế trong đó các giải pháp đã được phát triển và liệu điều đó có phù hợp với tình huống chúng ta đang gặp phải hay không.
Trong trường hợp của bạn, một đối tượng chức năng có vẻ như là một lựa chọn tốt. Nếu bạn đang tự hỏi tại sao một số hướng dẫn "thực hành tốt nhất" không đề cập đến các đối tượng hàm như một giải pháp khả thi, thì đó có thể đơn giản là vì các hướng dẫn đó được viết cho các phiên bản Java cũ!