Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

ЛР-6 / ЯП №6

.docx
Скачиваний:
1
Добавлен:
02.06.2026
Размер:
193.11 Кб
Скачать

Министерство науки и высшего образования Российской Федерации

Федеральное государственное автономное образовательное учреждение

высшего образования

ТОМСКИЙ ГОСУДАРСТВЕННЫЙ УНИВЕРСИТЕТ СИСТЕМ УПРАВЛЕНИЯ И РАДИОЭЛЕКТРОНИКИ (ТУСУР)

Кафедра безопасности информационных систем (БИС)

ОБЪЕКТНО-ОРИЕНТИРОВАННОЕ ПРОГРАММИРОВАНИЕ

Отчет по лабораторной работе №6

по дисциплине «Языки программирования»

Студент гр.

_______

_______

Принял:

Доцент каф. КИБЭВС, д.т.н., доцент

_______ Романов А. С.

_______

Оглавление

Введение 3

Ход работы 4

Заключение 6

Приложение А 7

Введение

Цель работы – знакомство с основными концепциями и приемами объектно-ориентированного анализа и проектирования, выработка практических навыков в построении модели предметной области и элементов модели проектирования. Код написан на ЯП Python.

Ход работы

Для данной лабораторной работы необходимо было разработать программу по варианту 19: Система управления уличным освещением на основе датчиков освещённости (рис 1.1). Листинг программы представлен в приложении А. Также была разработана UML-диаграмма, показывающая все связи классов (рис 1.2).

Рисунок 1.1 – Вывод для программы по варианту

Рисунок 1.2 – UML-диаграмма связей классов

Заключение

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

Приложение А

(обязательное)

Листинг кода для лабораторной работы

from abc import ABC, abstractmethod from typing import List, Set from datetime import time # интерфейс — контракт для классов, которые можно включать/выключать class Switchable(ABC):# абстрактный класс-интерфейс Switchable @abstractmethod# декоратор: метод обязателен к реализации def turn_on(self) -> None:# метод turn_on: включить устройство pass @abstractmethod# декоратор: метод обязателен к реализации def turn_off(self) -> None:# метод turn_off: выключить устройство pass @abstractmethod# декоратор: метод обязателен к реализации def is_on(self) -> bool:# метод is_on: проверить состояние включения pass #АБСТРАКТНЫЙ КЛАСС # базовый класс для всех устройств системы SOLID-I Если бы Switchable был частью Device — LightSensor был бы вынужден иметь пустые методы turn_on()/turn_off() class Device(ABC):# абстрактный класс Device, наследник ABC def __init__(self, device_id: str, name: str):# конструктор Device: принимает id и имя self._device_id = device_id self._name = name # хочешь добавить новое устройство? Создаёшь класс, наследуешь Device, реализуешь get_status_report() — не трогаешь существующий код. self.__status = "active"# SOLID-O def get_id(self) -> str:# селектор get_id: получить идентификатор return self._device_id def get_name(self) -> str:# селектор get_name: получить название return self._name @abstractmethod# декоратор: абстрактный метод def get_status_report(self) -> str:# метод get_status_report: отчёт о состоянии pass# реализация обязательна в подклассах #ПРОИЗВОДНЫЕ КЛАССЫ(Наследование) class LightFixture(Device, Switchable):# класс LightFixture: наследник Device, реализует Switchable def __init__(self, device_id: str, name: str, power_watts: float):# конструктор LightFixture super().__init__(device_id, name)# вызов конструктора базового класса Device self._power_watts = power_watts self.__is_on = False self._brightness = 100 def turn_on(self) -> None: self.__is_on = True print(f"светильник '{self._name}' ВКЛЮЧЕН") def turn_off(self) -> None: self.__is_on = False print(f"светильник '{self._name}' ВЫКЛЮЧЕН") def is_on(self) -> bool:# реализация метода интерфейса Switchable: проверка return self.__is_on def get_status_report(self) -> str:# реализация абстрактного метода Device: отчёт state = "ВКЛ" if self.__is_on else "ВЫКЛ" return f"светильник {self._name}: {state}, {self._power_watts}Вт, яркость {self._brightness}%" def set_brightness(self, level: int) -> None:# модификатор set_brightness: изменить яркость self._brightness = max(0, min(100, level)) print(f"яркость '{self._name}' установлена на {self._brightness}%") def get_power(self) -> float:# селектор get_power: текущее потребление if not self.__is_on: return 0.0 return self._power_watts * (self._brightness / 100.0) class LightSensor(Device):# класс LightSensor: наследник Device def __init__(self, device_id: str, name: str, threshold: float):# конструктор LightSensor super().__init__(device_id, name)# вызов конструктора базового класса Device self._threshold = threshold self.__current_lux = 0.0 # ТОЛЬКО измеряет свет # SOLID-S отвечает только за одно def read_light_level(self) -> float:# селектор read_light_level: прочитать освещённость return self.__current_lux def set_light_level(self, lux: float) -> None:# модификатор set_light_level: задать освещённость self.__current_lux = lux def is_dark(self) -> bool:# метод is_dark: проверка "темно ли?" return self.__current_lux < self._threshold def get_status_report(self) -> str:# реализация абстрактного метода Device: отчёт return f"датчик {self._name}: {self.__current_lux:.1f} люкс (порог: {self._threshold} люкс)" def calibrate(self, new_threshold: float) -> None:# модификатор calibrate: калибровка порога self._threshold = new_threshold print(f"датчик '{self._name}' откалиброван: порог = {self._threshold} люкс") #Композиция # класс LightingSchedule: часть StreetLight, не существует отдельно class LightingSchedule:# класс LightingSchedule: расписание работы фонаря def __init__(self, on_time: time, off_time: time):# конструктор LightingSchedule: время вкл/выкл self._on_time = on_time self._off_time = off_time self._enabled = True def is_active_time(self, current_time: time) -> bool:# метод is_active_time: проверка попадания во временной интервал if not self._enabled: return False if self._on_time <= self._off_time: return self._on_time <= current_time <= self._off_time else: return current_time >= self._on_time or current_time <= self._off_time # Ассоциация # класс StreetLight: ассоциирован с LightFixture и LightSensor (1 к 1) class StreetLight:# класс StreetLight: уличный фонарь def __init__(self, light_id: str, location: str, fixture: LightFixture, sensor: LightSensor):# конструктор self._light_id = light_id self._location = location self._sensor = sensor# ассоциация: ссылка на объект LightSensor self._fixture = fixture# ассоциация: ссылка на объект LightFixture self._schedule = LightingSchedule(# композиция: создание LightingSchedule внутри StreetLight on_time=time(20, 0), off_time=time(6, 0) ) self._auto_mode = True def update(self, current_time: time) -> None:# метод update: основная бизнес-логика обновления print(f"\nобновление фонаря '{self._light_id}' ({self._location})") print(f"датчик: {self._sensor.get_status_report()}") if self._auto_mode: if self._sensor.is_dark(): self._fixture.turn_on() else: self._fixture.turn_off() else: if self._schedule.is_active_time(current_time): self._fixture.turn_on() else: self._fixture.turn_off() print(f"{self._fixture.get_status_report()}") def get_power_consumption(self) -> float: return self._fixture.get_power() # Агрегация # класс LightingZone: агрегирует StreetLight (части могут существовать отдельно) class LightingZone:# класс LightingZone: зона освещения def __init__(self, zone_id: str, zone_name: str):# конструктор LightingZone self._zone_id = zone_id self._zone_name = zone_name self._lights: Set[StreetLight] = set()# агрегация: множество StreetLight (пустое по умолчанию) def add_light(self, light: StreetLight) -> None: self._lights.add(light) print(f"фонарь '{light._light_id}' добавлен в зону '{self._zone_name}'") def remove_light(self, light: StreetLight) -> None: self._lights.discard(light) print(f"фонарь '{light._light_id}' удалён из зоны '{self._zone_name}'") def get_total_power(self) -> float: return sum(light.get_power_consumption() for light in self._lights) def update_all(self, current_time: time) -> None: for light in self._lights: light.update(current_time) # Зависимость <<use>> # класс LightingController: зависит от LightingZone (принимает как параметр) class LightingController:# SOLID-D LightingController не зависит от LightFixture/LightSensor def __init__(self, controller_name: str):# конструктор LightingController self._name = controller_name self._zones: List[LightingZone] = [] def add_zone(self, zone: LightingZone) -> None: self._zones.append(zone) def monitor_zone(self, zone: LightingZone) -> None: print(f"зона: {zone._zone_name} ({len(zone._lights)} фонарей)") print(f"общее потребление: {zone.get_total_power():.2f} Вт") for light in zone._lights: print(f" {light._light_id}: {light._location}") def system_report(self) -> None:# метод system_report: отчёт по всей системе (зависимость) total_power = 0.0# локальная переменная total_power: суммарная мощность total_lights = 0# локальная переменная total_lights: суммарное число фонарей for zone in self._zones:# итерация по списку _zones power = zone.get_total_power()# мощность текущей зоны total_power += power# накопление total_power total_lights += len(zone._lights)# накопление total_lights print(f" {zone._zone_name}: {power:.2f} Вт")# вывод по зоне print(f"\nИТОГО: {total_lights} фонарей, {total_power:.2f} Вт")# итоговый вывод #SOLID # S Single Responsibility (Принцип единственной ответственности) Каждый класс должен отвечать только за одну вещь. # O Open/Closed (Принцип открытости/закрытости) Открыт для расширения, закрыт для изменения. # L Liskov Substitution (Принцип подстановки Лисков) Объект подкласса должен заменять объект базового класса без нарушения работы программы. # I Interface Segregation (Принцип разделения интерфейса) Клиенты не должны зависеть от методов, которые они не используют. # D Dependency Inversion (Принцип инверсии зависимостей) Модули верхнего уровня не должны зависеть от модулей нижнего уровня. Оба должны зависеть от абстракций. #ДЕМОНСТРАЦИЯ # создание светильников (экземпляры LightFixture) fixture1 = LightFixture("LF-001", "LED-Уличный-150", 150.0) fixture2 = LightFixture("LF-002", "LED-Уличный-100", 100.0) fixture3 = LightFixture("LF-003", "LED-Парк-80", 80.0) # создание датчиков (экземпляры LightSensor) sensor1 = LightSensor("SN-001", "Датчик-Центр", 30.0) sensor2 = LightSensor("SN-002", "Датчик-Север", 25.0) sensor3 = LightSensor("SN-003", "Датчик-Парк", 35.0) # демонстрация полиморфизма: список объектов разных классов, общий базовый Device devices: List[Device] = [fixture1, sensor1, fixture2, sensor2] # LightFixture и LightSensor — потомки Device Оба реализуют get_status_report() for device in devices: # Можно подставить LightSensor вместо Device — код for device in devices не сломается print(f"{device.get_status_report()}") #SOLID-L # создание фонарей (ассоциация: передача готовых объектов) street_light1 = StreetLight("SL-001", "ул. Ленина, 15", fixture1, sensor1) street_light2 = StreetLight("SL-002", "ул. Ленина, 45", fixture2, sensor2) street_light3 = StreetLight("SL-003", "парк Горького", fixture3, sensor3) # создание зон (агрегация: фонари существуют отдельно) central_zone = LightingZone("Z-01", "Центральный район") north_zone = LightingZone("Z-02", "Северный район") central_zone.add_light(street_light1) # агрегация: добавление street_light1 в central_zone central_zone.add_light(street_light2) # агрегация: добавление street_light2 в central_zone north_zone.add_light(street_light3) # агрегация: добавление street_light3 в north_zone # демонстрация низкая освещённость (темно) sensor1.set_light_level(10.0) sensor2.set_light_level(15.0) sensor3.set_light_level(5.0) current_time = time(21, 30) central_zone.update_all(current_time) north_zone.update_all(current_time) # создание контроллера (зависимость) controller = LightingController("Главный контроллер") # объект controller: контроллер системы controller.add_zone(central_zone) controller.add_zone(north_zone) controller.monitor_zone(central_zone) # зависимость: мониторинг central_zone controller.system_report() # зависимость: отчёт по всей системе # дополнительные методы производных классов fixture1.set_brightness(75) sensor1.calibrate(20.0) # демонстрация: высокая освещённость (светло) sensor1.set_light_level(150.0) sensor2.set_light_level(200.0) sensor3.set_light_level(120.0) current_time = time(9, 0) central_zone.update_all(current_time) north_zone.update_all(current_time) controller.system_report() # демонстрация композиции: расписание — часть фонаря print(f"\nКОМПОЗИЦИЯ: фонарь {street_light1._light_id} имеет расписание {street_light1._schedule._on_time}-{street_light1._schedule._off_time}") # демонстрация агрегации: удаление фонаря из зоны (фонарь продолжает существовать) central_zone.remove_light(street_light2) # удаление street_light2 из central_zone print(f"фонарь '{street_light2._light_id}' всё ещё существует: {street_light2._location}") # объект жив

Томск 2026

Соседние файлы в папке ЛР-6