💀
Второй курс РПО
Разработка программных модулей
Разработка программных модулей
  • Модели разработки
  • Ошибки и отладка программ
  • Средства разработки алгоритмов
    • Основные принципы и стадии тестирования
  • Сложностные классы
  • Эмуляторы операционных систем
  • Сложность сортировки
  • Уровни тестирования
  • Задание №1
  • Регрессионное тестирование
  • Тестирование «белым ящиком»
  • Как делать оценку сложности?
  • Алгоритмы и сложность
  • Тестирование "белым ящиком" №2
  • Сложность алгоритмов
  • Тестирование "белым ящиком" №3
  • Тестирование "Чёрным ящиком»" №1
  • Тестирование "Черным ящиком" №2
  • Оценка сложности эвристических алгоритмов
  • Принципы ООП
  • Тестирование "Черным ящиком" №3
  • КТ - В3
  • Модульное тестирование
    • С кодами
  • Модульное тестирование
  • Абстрактные классы и интерфейсы в Python
  • Структуры в Python по аналогии с C++
    • Диалоги гениев
  • Делегаты в Python
    • Ещё более не смешные диалоги
  • Регулярные выражения в Python от простого к сложному
  • Python: Коллекции
  • Параметризованные классы (шаблоны)
  • Указатели и операции со списками в Python
  • Интеграционное тестирование
  • Работа с классами. Перегрузка методов
  • Определение операций в классе.
  • Создание наследованных классов
  • Интеграционное тестирование
  • Работа с объектами через интерфейсы
  • Использование стандартных интерфейсов
  • Работа с типом данных "Структура"
  • Коллекции. Параметризованные классы
  • Использование регулярных выражений
  • Операции со списками
  • Что такое паттерны проектирования?
  • Шпаргалка по шаблонам проектирования
    • [Habr] Шпаргалка
  • UML-диаграммы проектирования
  • Использование основных шаблонов.
  • Использование каких то там шаблонов
  • 15-я Практическая
  • 16-я Практическая
  • Graphviz Online
  • 17-я Практическая
  • Введение в теорию программирования: Объектно-ориентированный подход
  • Документирование софта и стандарты
  • C# Ввод и вывод
  • Оптимизация кода: просто о главном
  • Автоматизация разработки технической документации
  • Автоматизированное документирование и первичные данные
  • ADO.NET что это?
Powered by GitBook
On this page
  • Схема IT TOP
  • Разбор структуры
  • Отношения
  • Используемые шаблоны
  • Как работают шаблоны?
  • Схема работы с Криптой
  • Разбор элементов диаграммы
  • Основные связи:

Использование основных шаблонов.

Практическая работа №14. Использование основных шаблонов. - 14.02.2025

PreviousUML-диаграммы проектированияNextИспользование каких то там шаблонов

Last updated 3 months ago

Текст практической №14

Практическая работа №14. Использование основных шаблонов. По 2-а шаблона из каждой группы, привести код и самостоятельно расписать и показать на схеме, как используется шаблон в этом коде

Схема IT TOP

Разбор структуры

  • Колледж IT TOP – центральный объект, имеющий бюджет, местоположение и учительский состав.

  • Студенты – имеют возраст, зачётную книжку и ФИО.

  • Учителя – содержат возраст, ФИО и номер телефона.

  • Компьютеры – включают характеристики, цвет и данные.

  • Столы, стулья – описаны материалом, формой, цветом и размером.

  • Дом – описан местоположением, размером и количеством жильцов.

Отношения

  • Колледж включает студентов и учителей.

  • Студенты и учителя могут использовать компьютеры.

  • Студенты и учителя живут в домах.


Используемые шаблоны

  1. Обобщённый класс (Equipment[T]) – для работы с характеристиками оборудования.

  2. Фабрика (Factory) – для создания объектов (Student и Teacher).


Код на Python

from typing import TypeVar, Generic

# Обобщённый класс для хранения характеристик оборудования
T = TypeVar('T')

class Equipment(Generic[T]):
    def __init__(self, characteristics: T, color: int, data: str):
        self.characteristics = characteristics
        self.color = color
        self.data = data

    def show_info(self):
        print(f"Характеристики: {self.characteristics}, Цвет: {self.color}, Данные: {self.data}")

# Базовый класс Человек
class Human:
    def __init__(self, age: int, name: str):
        self.age = age
        self.name = name

    def show_info(self):
        raise NotImplementedError("Метод show_info() должен быть переопределён в подклассе.")

# Класс Студент
class Student(Human):
    def __init__(self, age: int, name: str, has_record_book: bool):
        super().__init__(age, name)
        self.has_record_book = has_record_book

    def show_info(self):
        print(f"Студент: {self.name}, Возраст: {self.age}, Зачётная книжка: {'Есть' if self.has_record_book else 'Нет'}")

# Класс Учитель
class Teacher(Human):
    def __init__(self, age: int, name: str, phone_number: str):
        super().__init__(age, name)
        self.phone_number = phone_number

    def show_info(self):
        print(f"Учитель: {self.name}, Возраст: {self.age}, Телефон: {self.phone_number}")

# Шаблон "Фабрика" для создания студентов и учителей
class Factory:
    @staticmethod
    def create_student(age: int, name: str, has_record_book: bool) -> Student:
        return Student(age, name, has_record_book)

    @staticmethod
    def create_teacher(age: int, name: str, phone_number: str) -> Teacher:
        return Teacher(age, name, phone_number)

# Основная программа
if __name__ == "__main__":
    # Создание объектов через фабрику
    student1 = Factory.create_student(19, "Иван Иванов", True)
    teacher1 = Factory.create_teacher(35, "Мария Петрова", "89991234567")

    # Создание объекта компьютера через шаблонный класс
    comp1 = Equipment("Процессор: i5, RAM: 16GB", 1, "Windows 10")

    # Вывод информации
    student1.show_info()
    teacher1.show_info()
    comp1.show_info()
Пояснения к коду

1. Импортируем TypeVar и Generic

from typing import TypeVar, Generic

Здесь мы импортируем TypeVar и Generic, которые позволяют работать с универсальными типами данных. Это нужно для того, чтобы один класс мог работать с любыми типами данных.


2. Класс Equipment (Оборудование)

T = TypeVar('T')

Мы создаём универсальную переменную типа T, которая будет означать любой тип данных.

class Equipment(Generic[T]):

Этот класс принимает любой тип данных, указанный в T, и может работать с ним.

def __init__(self, characteristics: T, color: int, data: str):
  • characteristics: T — характеристики оборудования (например, процессор, память). Тип этих данных может быть любым.

  • color: int — цвет оборудования (например, 1 для чёрного, 2 для белого и т.д.).

  • data: str — строка с дополнительной информацией о оборудовании (например, версия операционной системы).

def show_info(self):
    print(f"Характеристики: {self.characteristics}, Цвет: {self.color}, Данные: {self.data}")

Метод выводит информацию о объекте на экран.


3. Класс Human (Человек)

class Human:

Базовый класс для всех людей. Он определяет, что у каждого человека есть возраст и имя.

def __init__(self, age: int, name: str):

Здесь мы задаём параметры age (возраст) и name (имя) для объекта.

def show_info(self):
    raise NotImplementedError("Метод show_info() должен быть переопределён в подклассе.")

Метод show_info() оставляем "пустым" (с ошибкой), потому что каждый наследник класса должен сам решить, как именно выводить информацию о себе.


4. Классы Student и Teacher

Оба этих класса наследуются от Human, то есть они уже имеют возраст и имя, но добавляют свои дополнительные особенности.

Класс Student:

class Student(Human):

Студент наследует базовые параметры от Human, но добавляет ещё одно свойство: наличие зачетной книжки.

def __init__(self, age: int, name: str, has_record_book: bool):
    super().__init__(age, name)
    self.has_record_book = has_record_book

Метод super() вызывает конструктор родительского класса Human, чтобы не повторять код для возраста и имени. has_record_book — это флаг, указывающий, есть ли у студента зачётная книжка.

def show_info(self):
    print(f"Студент: {self.name}, Возраст: {self.age}, Зачётная книжка: {'Есть' if self.has_record_book else 'Нет'}")

Метод show_info выводит информацию о студенте.

Класс Teacher:

class Teacher(Human):

Учитель также наследует все параметры от Human, но добавляет свойство с номером телефона.

def __init__(self, age: int, name: str, phone_number: str):
    super().__init__(age, name)
    self.phone_number = phone_number

Здесь, кроме возраста и имени, мы добавляем ещё телефон.

def show_info(self):
    print(f"Учитель: {self.name}, Возраст: {self.age}, Телефон: {self.phone_number}")

Метод show_info выводит информацию об учителе.


5. Фабрика для создания студентов и учителей

class Factory:

Класс Factory предоставляет методы для создания объектов Student и Teacher.

@staticmethod
def create_student(age: int, name: str, has_record_book: bool) -> Student:
    return Student(age, name, has_record_book)

Этот статический метод создаёт объект Student. Он не зависит от экземпляра класса, просто возвращает новый объект.

@staticmethod
def create_teacher(age: int, name: str, phone_number: str) -> Teacher:
    return Teacher(age, name, phone_number)

Аналогичный метод для создания учителя.


6. Основная программа

if __name__ == "__main__":

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

student1 = Factory.create_student(19, "Иван Иванов", True)
teacher1 = Factory.create_teacher(35, "Мария Петрова", "89991234567")

Создаём объекты студента и учителя через фабрику.

comp1 = Equipment("Процессор: i5, RAM: 16GB", 1, "Windows 10")

Создаём объект Equipment с характеристиками компьютера.

student1.show_info()
teacher1.show_info()
comp1.show_info()

Выводим информацию о студенте, учителе и компьютере.


Резюме:

  • Мы создали несколько классов для людей и объектов (студентов, учителей, оборудования).

  • Использовали типизацию с универсальными типами (через TypeVar), чтобы класс мог работать с любыми данными.

  • Всё это собрано в фабрику, которая упрощает создание объектов.


Как работают шаблоны?

  1. Обобщённый класс (Equipment[T]):

    • Позволяет хранить характеристики оборудования любого типа (string, int, float, dict и т. д.).

    • В данном примере создан объект comp1 с str в качестве типа характеристик.

  2. Фабрика (Factory):

    • Инкапсулирует создание объектов Student и Teacher, упрощая их создание.

    • Объекты создаются с Factory.create_student(...) и Factory.create_teacher(...), вместо явного вызова конструктора.


Выходные данные программы

Студент: Иван Иванов, Возраст: 19, Зачётная книжка: Есть
Учитель: Мария Петрова, Возраст: 35, Телефон: 89991234567
Характеристики: Процессор: i5, RAM: 16GB, Цвет: 1, Данные: Windows 10

Схема работы с Криптой

Разбор элементов диаграммы

Акторы (пользователи)

  • Влад Вишня – вероятно, пользователь криптобиржи, который привлекает реферальные ссылки.

  • Гениальный Ваня – другой пользователь, который может разрабатывать схемы.

Сценарии (Use Cases)

  • Работа с криптобиржей – основной процесс, включающий несколько сценариев.

    • Изучить "Как работать с криптобиржей" (include) – изучение базовой информации.

    • Разбогатеть на криптобирже – попытка заработать.

    • Разориться – возможный неудачный исход.

    • Привлечь реферальной ссылкой – привлечение пользователей по реферальной программе.

    • Исполнить свою схему – реализация стратегии.

      • Разработал свою схему "Как облопошить криптобиржу" (extend) – вариант схемы.

Основные связи:

  • Include – означает, что процесс работы с биржей обязательно включает изучение основ.

  • Extend – означает, что работа с биржей может расширяться нестандартными схемами.


Используемые шаблоны:

  1. Фабрика (UserFactory) – создаёт пользователей.

  2. Стратегия (CryptoStrategy) – задаёт разные подходы к работе с криптобиржей.

  3. Наследование и полиморфизм – классы VladVishnya и GeniusVanya наследуются от User.


Код на Python

from abc import ABC, abstractmethod

# Базовый класс пользователя криптобиржи
class User(ABC):
    def __init__(self, name):
        self.name = name

    @abstractmethod
    def work_with_crypto(self):
        pass

# Влад Вишня - использует реферальные ссылки
class VladVishnya(User):
    def __init__(self):
        super().__init__("Влад Вишня")

    def work_with_crypto(self):
        print(f"{self.name} привлекает пользователей по реферальной ссылке.")

# Гениальный Ваня - разрабатывает схемы
class GeniusVanya(User):
    def __init__(self):
        super().__init__("Гениальный Ваня")

    def work_with_crypto(self):
        print(f"{self.name} разрабатывает хитрую схему.")

# Фабрика пользователей
class UserFactory:
    @staticmethod
    def create_user(user_type):
        if user_type == "VladVishnya":
            return VladVishnya()
        elif user_type == "GeniusVanya":
            return GeniusVanya()
        else:
            return None

# Стратегия работы с криптобиржей
class CryptoStrategy(ABC):
    @abstractmethod
    def execute(self):
        pass

# Честная стратегия
class HonestStrategy(CryptoStrategy):
    def execute(self):
        print("Работаю честно: покупаю, продаю, привлекаю рефералов.")

# Спекулятивная стратегия
class ScamStrategy(CryptoStrategy):
    def execute(self):
        print("Придумал схему: ищу лазейки в криптобирже.")

# Контекст для выбора стратегии
class CryptoTrader:
    def __init__(self):
        self.strategy = None

    def set_strategy(self, strategy):
        self.strategy = strategy

    def trade(self):
        if self.strategy:
            self.strategy.execute()
        else:
            print("Стратегия не установлена!")

# Основная программа
if __name__ == "__main__":
    # Создаём пользователей через фабрику
    users = [UserFactory.create_user("VladVishnya"), UserFactory.create_user("GeniusVanya")]

    # Каждый пользователь работает с криптобиржей
    for user in users:
        if user:
            user.work_with_crypto()

    # Создаём торговца, который меняет стратегии
    trader = CryptoTrader()

    print("\nВыбираем честную стратегию:")
    trader.set_strategy(HonestStrategy())
    trader.trade()

    print("\nВыбираем спекулятивную стратегию:")
    trader.set_strategy(ScamStrategy())
    trader.trade()
Пояснения к коду

1. Импортируем ABC и abstractmethod

from abc import ABC, abstractmethod

Мы импортируем ABC (Abstract Base Class) и abstractmethod, чтобы создать абстрактные классы и методы. Абстрактные классы не могут быть созданы напрямую, они служат как шаблоны для других классов. Абстрактные методы нужно обязательно переопределить в подклассах.


2. Базовый класс User (Пользователь)

class User(ABC):
    def __init__(self, name):
        self.name = name

Это абстрактный класс для пользователей криптобиржи. Он задаёт атрибут name, который будет у каждого пользователя.

@abstractmethod
def work_with_crypto(self):
    pass

work_with_crypto — абстрактный метод, который должен быть переопределён в каждом подклассе. Он описывает, как пользователь будет работать с криптовалютой, но конкретная реализация остаётся за потомками.


3. Класс VladVishnya (Пользователь с реферальной ссылкой)

class VladVishnya(User):
    def __init__(self):
        super().__init__("Влад Вишня")

Это класс для пользователя Влад Вишня. Он наследует от User и вызывает конструктор родительского класса, передавая имя.

def work_with_crypto(self):
    print(f"{self.name} привлекает пользователей по реферальной ссылке.")

Метод work_with_crypto реализует логику для Влада Вишни — он использует реферальные ссылки.


4. Класс GeniusVanya (Гениальный разработчик схем)

class GeniusVanya(User):
    def __init__(self):
        super().__init__("Гениальный Ваня")

Это класс для пользователя Гениальный Ваня. Он тоже наследует от User и передаёт своё имя в конструктор родительского класса.

def work_with_crypto(self):
    print(f"{self.name} разрабатывает хитрую схему.")

Метод work_with_crypto для Гениального Вани реализует логику работы с криптовалютой, где он разрабатывает схемы.


5. Фабрика пользователей UserFactory

class UserFactory:
    @staticmethod
    def create_user(user_type):
        if user_type == "VladVishnya":
            return VladVishnya()
        elif user_type == "GeniusVanya":
            return GeniusVanya()
        else:
            return None

UserFactory — это фабрика для создания пользователей. В зависимости от строки user_type, она создаёт либо VladVishnya, либо GeniusVanya. Если тип неизвестен, возвращается None.


6. Абстрактная стратегия работы с криптобиржей CryptoStrategy

class CryptoStrategy(ABC):
    @abstractmethod
    def execute(self):
        pass

CryptoStrategy — абстрактный класс, который определяет метод execute для всех стратегий работы с криптобиржей. Этот метод будет переопределён в разных стратегиях.


7. Реализация стратегий: честная и спекулятивная

Честная стратегия HonestStrategy

class HonestStrategy(CryptoStrategy):
    def execute(self):
        print("Работаю честно: покупаю, продаю, привлекаю рефералов.")

HonestStrategy реализует честную стратегию: работает с криптовалютой по стандартным, прозрачным правилам.

Спекулятивная стратегия ScamStrategy

class ScamStrategy(CryptoStrategy):
    def execute(self):
        print("Придумал схему: ищу лазейки в криптобирже.")

ScamStrategy — это стратегия для тех, кто ищет лазейки и пытается обмануть систему.


8. Контекст для выбора стратегии CryptoTrader

class CryptoTrader:
    def __init__(self):
        self.strategy = None

    def set_strategy(self, strategy):
        self.strategy = strategy

    def trade(self):
        if self.strategy:
            self.strategy.execute()
        else:
            print("Стратегия не установлена!")

CryptoTrader — класс, который управляет текущей стратегией торговли. У него есть метод set_strategy, который позволяет выбрать стратегию (например, честную или спекулятивную), и метод trade, который выполняет выбранную стратегию.


9. Основная программа

if __name__ == "__main__":

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

users = [UserFactory.create_user("VladVishnya"), UserFactory.create_user("GeniusVanya")]

Создаём два объекта — VladVishnya и GeniusVanya — с помощью фабрики.

for user in users:
    if user:
        user.work_with_crypto()

Каждый пользователь работает с криптовалютой, выполняя свой метод work_with_crypto.

trader = CryptoTrader()

print("\nВыбираем честную стратегию:")
trader.set_strategy(HonestStrategy())
trader.trade()

print("\nВыбираем спекулятивную стратегию:")
trader.set_strategy(ScamStrategy())
trader.trade()

Создаём торговца CryptoTrader, устанавливаем для него честную стратегию и запускаем её. Потом меняем стратегию на спекулятивную и снова запускаем.


Резюме:

  • Мы создали абстрактный класс User, который описывает пользователей криптобиржи, и два класса-потомка: VladVishnya и GeniusVanya, каждый из которых реализует свою стратегию работы с криптовалютой.

  • Фабрика UserFactory помогает создавать объекты пользователей.

  • Стратегии работы с криптобиржей описаны в классе CryptoStrategy. Мы реализовали честную и спекулятивную стратегии.

  • Класс CryptoTrader позволяет менять стратегии торговли и выполнять их.


Как работает этот код?

  1. Создаются пользователи через фабрику (UserFactory):

    • VladVishnya – привлекает пользователей по реферальным ссылкам.

    • GeniusVanya – разрабатывает схемы.

  2. Используется паттерн "Стратегия" (CryptoStrategy):

    • HonestStrategy – честная торговля.

    • ScamStrategy – махинации.

  3. Объект CryptoTrader может менять стратегию торговли.


Выходные данные программы

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

Выбираем честную стратегию:
Работаю честно: покупаю, продаю, привлекаю рефералов.

Выбираем спекулятивную стратегию:
Придумал схему: ищу лазейки в криптобирже.