Применяешь ли принципы ООП в своей работе

«Применяешь ли принципы ООП в своей работе» — вопрос из категории ООП, который задают на 26% собеседований Data Scientist / ML Инженер. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Да, активно применяю принципы ООП в разработке. Вот как я их использую на практике:

1. Инкапсуляция Скрываю внутреннюю реализацию и предоставляю четкий интерфейс:

class PaymentProcessor:
    def __init__(self, api_key):
        self._api_key = api_key  # приватный атрибут
        self._connection = self._establish_connection()

    def _establish_connection(self):
        # внутренняя логика подключения
        return f"Connection with key: {self._api_key[:5]}..."

    def process_payment(self, amount, currency):
        # публичный метод
        return self._make_api_call(amount, currency)

    def _make_api_call(self, amount, currency):
        # приватный метод
        return f"Processed {amount} {currency}"

2. Наследование Использую для создания иерархий классов и повторного использования кода:

class Vehicle:
    def __init__(self, brand, model):
        self.brand = brand
        self.model = model

    def get_info(self):
        return f"{self.brand} {self.model}"

class ElectricCar(Vehicle):
    def __init__(self, brand, model, battery_capacity):
        super().__init__(brand, model)
        self.battery_capacity = battery_capacity

    def get_info(self):
        base_info = super().get_info()
        return f"{base_info}, Battery: {self.battery_capacity} kWh"

3. Полиморфизм Работаю с объектами разных типов через общий интерфейс:

class Shape:
    def area(self):
        raise NotImplementedError

class Rectangle(Shape):
    def __init__(self, width, height):
        self.width = width
        self.height = height

    def area(self):
        return self.width * self.height

class Circle(Shape):
    def __init__(self, radius):
        self.radius = radius

    def area(self):
        return 3.14 * self.radius ** 2

# Полиморфное использование
shapes = [Rectangle(4, 5), Circle(3)]
total_area = sum(shape.area() for shape in shapes)

4. Абстракция Создаю абстрактные классы для определения контрактов:

from abc import ABC, abstractmethod

class DatabaseConnector(ABC):
    @abstractmethod
    def connect(self):
        pass

    @abstractmethod
    def execute_query(self, query):
        pass

class PostgreSQLConnector(DatabaseConnector):
    def connect(self):
        return "Connected to PostgreSQL"

    def execute_query(self, query):
        return f"Executing: {query}"

Практические примеры из моего опыта:

  • Создавал систему плагинов, где каждый плагин — отдельный класс с общим интерфейсом
  • Разрабатывал ORM-подобную прослойку для работы с разными базами данных
  • Строил иерархии обработчиков данных с наследованием общей логики

Когда ООП особенно полезен:

  • При разработке сложных систем с четкими сущностями
  • Когда нужна легкая расширяемость через наследование
  • Для инкапсуляции сложной бизнес-логики

Альтернативы: Для простых скриптов или функциональных преобразований данных иногда использую функциональный подход, но ООП остается основой для структурирования больших приложений.