← Назад к вопросам

Приведи примеры ООП

2.0 Middle🔥 181 комментариев
#API тестирование#Теория тестирования

Комментарии (1)

🐱
deepseek-v3.2PrepBro AI6 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Примеры использования ООП в программировании

Объектно ООП предоставляет инструменты для создания модульных, масштабируемых и поддерживаемых систем. Вот практические примеры из разных областей.

1. Моделирование реальных сущностей в приложениях

Пример: система управления библиотекой

class Book:
    def __init__(self, title: str, author: str, isbn: str):
        self.title = title
        self.author = author
        self.isbn = isbn
        self.is_available = True

    def borrow(self):
        if self.is_available:
            self.is_available = False
            return True
        return False

    def return_book(self):
        self.is_available = True

    def __str__(self):
        return f"{self.title} by {self.author}"

class LibraryMember:
    def __init__(self, member_id: str, name: str):
        self.member_id = member_id
        self.name = name
        self.borrowed_books: list[Book] = []

    def borrow_book(self, book: Book):
        if book.borrow():
            self.borrowed_books.append(book)
            return True
        return False

    def return_book(self, book: Book):
        if book in self.borrowed_books:
            book.return_book()
            self.borrowed_books.remove(book)

class Library:
    def __init__(self):
        self.books: dict[str, Book] = {}
        self.members: dict[str, LibraryMember] = {}

    def add_book(self, book: Book):
        self.books[book.isbn] = book

    def register_member(self, member: LibraryMember):
        self.members[member.member_id] = member

# Использование
library = Library()
book1 = Book("Clean Code", "Robert Martin", "978-0132350884")
member1 = LibraryMember("001", "Иван Петров")

library.add_book(book1)
library.register_member(member1)

member1.borrow_book(book1)
print(f"{member1.name} взял книгу: {book1.title}")

Это демонстрирует инкапсуляцию (данные и методы внутри классов), наследование можно добавить для разных типов книг (например, EBook extends Book), и полиморфизм при обработке разных типов объектов.

2. Абстракция и интерфейсы в тестировании

Пример: фреймворк для автоматизации тестирования

// Абстракция для тестовых действий
interface WebDriver {
    void click(String elementId);
    String getText(String elementId);
    void navigateTo(String url);
}

// Конкретная реализация
class ChromeDriver implements WebDriver {
    @Override
    public void click(String elementId) {
        System.out.println("Clicking element " + elementId + " in Chrome");
        // Реальная реализация через Selenium
    }

    @Override
    public String getText(String elementId) {
        return "Text from element";
    }
}

// Абстракция для тестовых страниц
abstract class BasePage {
    protected WebDriver driver;

    public BasePage(WebDriver driver) {
        this.driver = driver;
    }

    public abstract void open();
}

// Конкретная страница
class LoginPage extends BasePane {
    private final String loginButtonId = "loginBtn";

    public LoginPage(WebDriver driver) {
        super(driver);
    }

    @Override
    public void open() {
        driver.navigateTo("https://app.com/login");
    }

    public void performLogin() {
        driver.click(loginButtonId);
    }
}

// Тестовый класс использующий эти абстракции
class LoginTest {
    private WebDriver driver;
    private LoginPage loginPage;

    @BeforeTest
    public void setup() {
        driver = new ChromeDriver();
        loginPage = new LoginPage(driver);
    }

    @Test
    public void testSuccessfulLogin() {
        loginPage.open();
        loginPage.performLogin();
        // Проверки
    }
}

Это показывает инкапсуляцию деталей реализации драйвера, абстракцию через интерфейсы, и возможность полиморфизма – легко заменить ChromeDriver на FirefoxDriver.

3. Полиморфизм и наследование в расчетах

Пример: система расчетов платежей с разными типами пользователей

from abc import ABC, abstractmethod

class PaymentCalculator(ABC):
    @abstractmethod
    def calculate_amount(self, base_price: float) -> float:
        pass

class RegularCustomerCalculator(PaymentCalculator):
    def calculate_amount(self, base_price: float) -> float:
        return base_price  # без скидки

class PremiumCustomerCalculator(PaymentCalculator):
    def calculate_amount(self, base_price: float) -> float:
        return base_price * 0.85  # 15% скидка

class VipCustomerCalculator(PaymentCalculator):
    def calculate_amount(self, base_price: float) -> float:
        return base_price * 0.70  # 30% скидка

class Order:
    def __init__(self, base_price: float, calculator: PaymentCalculator):
        self.base_price = base_price
        self.calculator = calculator

    def final_price(self) -> float:
        return self.calculator.calculate_amount(self.base_price)

# Использование с полиморфизмом
orders = [
    Order(1000.0, RegularCustomerCalculator()),
    Order(1000.0, PremiumCustomerCalculator()),
    Order(1000.0, VipCustomerCalculator())
]

for order in orders:
    print(f"Final price: {order.final_price()}")

4. Инкапсуляция и управление состоянием

Пример: управление конфигурацией в тестовом фреймворке

class TestConfig:
    def __init__(self):
        self._settings = {
            "timeout": 30,
            "base_url": "http://localhost",
            "headless": False
        }

    # Инкапсуляция: доступ через методы
    def get_setting(self, key: str):
        return self._settings.get(key)

    def update_setting(self, key: str, value):
        if key in self._settings:
            self._settings[key] = value
        else:
            raise KeyError(f"Unknown setting: {key}")

    def reset_to_defaults(self):
        self._settings = {
            "timeout": 30,
            "base_url": "http://localhost",
            "headless": False
        }

# Использование
config = TestConfig()
print(f"Timeout: {config.get_setting('timeout')}")
config.update_setting("headless", True)

# Защита от некорректных изменений
try:
    config.update_setting("unknown_key", "value")
except KeyError as e:
    print(e)

Это предотвращает прямое изменение внутренних данных, обеспечивая контролируемый доступ.

5. Композиция и агрегация для сложных систем

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

class TestResult:
    def __init__(self, test_name: str, status: str):
        self.test_name = test_name
        self.status = status

class ReportSection:
    def __init__(self, title: str):
        self.title = title
        self.results: list[TestResult] = []

    def add_result(self, result: TestResult):
        self.results.append(result)

    def get_stats(self):
        passed = sum(1 for r in self.results if r.status == "PASSED")
        return {"total": len(self.results), "passed": passed}

class TestReport:
    def __init__(self):
        self.sections: dict[str, ReportSection] = {}

    def add_section(self, section: ReportSection):
        self.sections[section.title] = section

    def generate_summary(self):
        summary = {}
        for title, section in self.sections.items():
            summary[title] = section.get_stats()
        return summary

# Создание сложного объекта через композицию
report = TestReport()
ui_section = ReportSection("UI Tests")
api_section = ReportSection("API Tests")

ui_section.add_result(TestResult("Login test", "PASSED"))
api_section.add_result(TestResult("Get users", "FAILED"))

report.add_section(ui_section)
report.add_section(api_section)

print(report.generate_summary())

ООП позволяет моделировать сложные отношения между объектами, делая код более понятным и управляемым.

Ключевые преимущества ООП в этих примерах:

  • Модульность: каждый класс имеет четкую ответственность
  • Расширяемость: новые типы объектов добавляются без изменения существующих (Open-Closed Principle)
  • Сопровождаемость: изменения локализованы в конкретных классах
  • Тестируемость: объекты можно тестировать независимо
  • Реиспользование: базовые классы и интерфейсы используются в разных контекстах

В QA Automation ООП особенно полезен для создания:

  1. Абстрактных фреймворков тестирования
  2. Page Object моделей (каждый page - отдельный класс)
  3. Гибких отчетных систем
  4. Управления тестовыми данными через специализированные классы
  5. Плагинов и расширений через наследование и интерфейсы

Эти подходы уменьшают дублирование кода, улучшают читабельность и позволяют масштабировать тестовые инфраструктуры.

Приведи примеры ООП | PrepBro