Приведи примеры ООП
Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Примеры использования ООП в программировании
Объектно ООП предоставляет инструменты для создания модульных, масштабируемых и поддерживаемых систем. Вот практические примеры из разных областей.
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 ООП особенно полезен для создания:
- Абстрактных фреймворков тестирования
- Page Object моделей (каждый page - отдельный класс)
- Гибких отчетных систем
- Управления тестовыми данными через специализированные классы
- Плагинов и расширений через наследование и интерфейсы
Эти подходы уменьшают дублирование кода, улучшают читабельность и позволяют масштабировать тестовые инфраструктуры.