ПКС / ПКС. Материалы лекций
.pdf4. Шаблоны проектирования критических сервисов |
|
141 |
21) Цепочка обязанностей (Chain Of Responsibility)
Шаблон «Цепочка обязанностей» позволяет смоделировать единообразную (через общий интерфейс) структуру объектов, связанных разной степенью ответственности выполнения действий: чем больше уровень вложения («перекладывания» ответственности), тем более глобальные действия применяются.
Примеры:
Обработка действий внутри предприятия, учитывая схему подчинения.
Обработка действий при выполнении типовой задачи, обусловленной пользовательским запросом (обработка нажатия клавиши «F1» пользователем: сначала ближайшим контрОлом, затем соответствующим окном настроек, затем еще более главным окном).
область
обращения к «логу»
область
реализации
рекурсив-
ного вызова объектов «лога»
область обработки «лога»: более высокий уровень (_level) – для более «ответственных» решений
4. Шаблоны проектирования критических сервисов |
|
142 |
21) Цепочка обязанностей (Chain Of Responsibility)
Шаблон «Цепочка обязанностей» реализуются с помощью «неявного» интер-
фейса (AbstractLogger), в
котором представлена логика «перекладывания» отвественности на внутренний объект такого же типа
(#nextLogger), пока его зна-
чение не null.
4. Шаблоны проектирования критических сервисов |
|
143 |
22) Посетитель (Visitor, “Визитер”)
Шаблон Визитер (Посетитель) предназначен для обработки структур: их отображения, расчета (одинаковых действий над конкретными типовыми объектами). Примеры: дерево каталогов, подсказки (hint).
область структуры данных (обычно это Комповщик)
область контекстных объектов-«визитеров»,
привязанных к определенной структуре данных
область обращения пользователя к структуре, обычно древовидной (реализованной с помощью\
Компоновщика).
4. Шаблоны проектирования критических сервисов |
|
144 |
23) Интерпретатор (Interpreter)
Шаблон Интерпретатор позволяет перевести одну систему объектов («источник», source) к другой (приемник, destiny) через общий интерфейс обработки (Expression) для дальнейшего «перевода» объектов (NonTerminal) и для их конечного представления (Terminal) - при заданных условиях
(OrExpression, AndExpression).
область «перевода» |
область |
|
использования |
||
от одной системы |
||
«переводчика» |
||
объектов к другой |
||
|
||
(пока «предложение» |
|
|
(NonTerminal) не раз- |
|
|
ложено на конечные |
|
|
«слова и фразы» (Ter- |
|
|
minal), продол- |
|
|
жается его даль- |
|
|
нейшее упрощение) |
|
область контекста «перевода» (определения системы объектов «источника» и «приемника»)
Список литературы |
145 |
1. Шпаргалка по шаблонам проектирования [Электронный ресурс]. – 2014. – URL: https://habr.com/ru/post/210288/
2. Паттерны/шаблоны проектирования [Электронный ресурс]. – 2021. – URL: https://refactoring.guru/ru/design-patterns 3. Gamma, E. Design Patterns. Elements of Reusable Object-Oriented Software : [Text] / E. Gamma, R. Helm, R. Johnson, J. Vlissides // Forework by Grady Booch. – 37th printing. – Boston: Adisson-Wesley, 2009. 417 p.
4. Фримен, Э. Паттерны проектирования : [Электронный ресурс] / Э. Фримен [и др.]. – Санкт-Петербург : Питер, 2017. –
656 с. : ил. – URL: http://ibooks.ru/reading.php?productid=354827
5. Pattern: Microservice Architecture [Electronic Resource]. – 2018. – URL: https://microservices.io/patterns/microservices.html
6. Плас, Дж. Вандер. Python для сложных задач: наука о данных и машинное обучение : [Электронный ресурс] / Дж.
Вандер Плас. – Санкт-Петербург : Питер, 2018. – 576 с. : ил. – URL: http://ibooks.ru/reading.php?productid=356721
7. Северенс, Ч. Введение в программирование на Python : [Электронный ресурс]: учебное пособие / Ч. Северенс. – 2-е
изд. – Москва : ИНТУИТ, 2016. 231 с. – URL: https://e.lanbook.com/book/100703
8. Practical Microservices Development Patterns: CRUD Vs. CQRS : [Electronic Resource]. – 2020. – URL: https://hackernoon.com/practical-microservices-development-patterns-crud-vs-cqrs-h6m3y5y
9.Eventuate example microservices applications : [Electronic Resource]. – 2021. – URL: https://eventuate.io/exampleapps.html
10.Онлайн-редактор диаграмм PlantText [Электронный ресурс]. – URL: https://www.planttext.com/, https://www.plantuml.com/plantuml
11.About the Unified Modeling Language Specification Version 2.5.1 [Electronic Resource]. – 2017. – 754 p. – URL: https://www.omg.org/spec/UML/2.5.1
12.Fowler, M. UML Distilled: A Brief Guide to the Standard Object Modeling Language [Text] / M. Fowler. – 3rd Ed. Boston: Addison-Wesley, 2003. – 178 p.
МИНИСТЕРСТВО ЦИФРОВОГО РАЗВИТИЯ, СВЯЗИ И МАССОВЫХ КОММУНИКАЦИЙ РОССИЙСКОЙ ФЕДЕРАЦИИ
ФЕДЕРАЛЬНОЕ ГОСУДАРСТВЕННОЕ БЮДЖЕТНОЕ ОБРАЗОВАТЕЛЬНОЕ УЧРЕЖДЕНИЕ ВЫСШЕГО ОБРАЗОВАНИЯ «САНКТ-ПЕТЕРБУРГСКИЙ ГОСУДАРСТВЕННЫЙ УНИВЕРСИТЕТ ТЕЛЕКОММУНИКАЦИЙ ИМ. ПРОФ. М.А. БОНЧ-БРУЕВИЧА» (СПбГУТ)
Кафедра информационных управляющих систем
Б1.В.24 «Программирование критических сервисов» для специальностей по направлению 09.03.02 «Информационные системы и технологии»
1.Cервисы программного обеспечения в международных стандартах.
2.Cервисы программного обеспечения в российских стандартах.
3.Критические объекты и процессы программных средств в международных стандартах.
4.Шаблоны проектирования критических сервисов.
5.Программные компоненты для создания критического сервиса на языке Python.
6.Программные решения на основе критических сервисов в задаче развертывания микросервисной архитектуры.
Преподаватель: Параничев Андрей Викторович
Санкт-Петербург 2023
5. Программные компоненты для создания критического сервиса на языке Python 147
5.1) Постановка задачи создания критического сервиса:
•требования к критическому сервису на основе определения критической секции (critical section);
•пример постановки задачи в концепции CRUD (Create, Read, Update, Delete).
5.2) Выбор инструментария:
•обзор фреймворков (framework), плагинов (plugin) и расширений (extension) на языке Python;
•пример установки фреймворка PyCharm и набора расширений.
5.3) Программная реализация критического сервиса:
• обзор команд на языке Python для работы с окружением и базами данных.
•пример реализации сервиса CRUD на основе Selenium.
5.4) Тестирование критического сервиса:
•обзор средств юнит-тестирования на языке Python.
•примеры юнит-тестов по результатам реализации сервиса CRUD на основе Selenuim.
5.5) Определение требований к развертыванию микросервисной архитектуры:
•микросервисная архитектура (MSA, microservice architecture), UML-диаграмма развертывания (deployment) и критический сервис с точки зрения реализации шаблона MVC;
•описание требований к развертыванию микросервисной архитектуры с помощью UML-диаграммы прецедентов
(usecase).
5. Пример кода для автоматизации в мессенджере WhatsApp (файл wb_unread.py) 148
from selenium import webdriver
from selenium.common.exceptions import NoSuchElementException from selenium.webdriver.common.by import By
import json import time
from tb_settings import TB_USERPATH, TB_DRIVER
# функция подготовки к запуску и выполнение запуска в браузере def simple_prepare():
try:
web_options = webdriver.ChromeOptions() web_options.add_argument(TB_USERPATH)
bot_driver = webdriver.Chrome(executable_path=TB_DRIVER, options=web_options) bot_driver.maximize_window()
print("Загрузка драйвера выполнена успешно!)") except:
print("Загрузка драйвера не выполнена!(") return None
try:
file_cookies = "tb_cookies.json" bot_driver.get("https://web.whatsapp.com") time.sleep(5)
print("Выполнена загрузка сайта") bot_cookies = bot_driver.get_cookies() print(bot_cookies)
with open(file_cookies, "r") as openfile: bot_cookies = json.load(openfile)
except IOError:
print("Файл tb_cookies.json пока не существует") try:
# запоминаем файл с куками json_object = json.dumps(file_cookies) with open(file_cookies, "w") as outfile:
outfile.write(json_object)
print("Файл с настройками успешно сохранен!)") except:
print("Файл с настройками не сохранен!(") return None
return bot_driver
# функция получения числа чатов def simple_chat_count(bot_driver):
row_count = 0
for num in range(1, 10): try:
time.sleep(1)
row_count = bot_driver.find_element(By.XPATH, '//*[@id="paneside"]/div[1]/div/div').\
get_attribute("aria-rowcount") break
except:
print("Чаты пока не найдены") row_count = 0
return int(row_count)
5. Пример кода для автоматизации в мессенджере WhatsApp (файл wb_unread.py) 149
#функция нахождения нового сообщения по номеру чата def is_new_message(bot_driver, number):
msg = "" try:
bot_driver.find_element(By.XPATH, '//*[@id="pane-
side"]/div[1]/div/div/div[{}]/div/div/div[2]/div[2]/div[2]/span[1]/div'.
format(number))
print("Есть новое сообщение для чата №{}!".format(number)) return 0
except:
print("Нет нового сообщения для чата {}!(".format(number)) return -1
#получение текста последнего нового сообщения от контакта по номеру чата (если есть новое сообщение)
def get_unread_contact_message(bot_driver, number):
msg_contact = None try:
msg_contact = bot_driver.find_element(By.XPATH, '//*[@id="pane-
side"]/div[1]/div/div/div[{}]/div/div/div[2]/div[2]/div[1]/span/span'. format(number)).text
except:
print("Нового сообщения для чата (в виде контакта) {} не получено!".format(number))
return msg_contact
# получение текста последнего нового сообщения от группы по номеру чата (если есть новое сообщение)
def get_unread_group_message(bot_driver, number): msg_group = None
try:
msg_group = bot_driver.find_element(By.XPATH, '//*[@id="pane-
side"]/div[1]/div/div/div[{}]/div/div/div[2]/div[2]/div[1]/span/span[3]'. format(number)).text
except:
print("Нового сообщения для чата (в виде группы) {} не
получено!".format(number)) return msg_group
# получение текста последнего сообщения от группы/контакта def get_last_unread_message(bot_driver, number):
msg = None try:
# если сообщение отправлено в группу, а не от контакта, то в span[1] - отправитель, в span[3] - само сообщение
msg = get_unread_group_message(bot_driver, number) if msg is None:
msg = get_unread_contact_message(bot_driver, number) except:
print("Нового сообщения для чата {} не получено!".format(number)) if msg is not None:
print("Получение новое сообщение для чата №{}:\n{}".format(number, msg)) return msg
5. Пример кода для автоматизации в мессенджере WhatsApp (файл wb_unread.py) 150
# перечисление новых сообщений в чатах def show_new_messages(bot_driver):
ret_value = 0 try:
num_chats = simple_chat_count(bot_driver) for num in range(1, int(num_chats)+1):
if is_new_message(bot_driver, num) >= 0:
msg = get_last_unread_message(bot_driver, num) if msg is None:
ret_value = -6
except:
print("Ошибка в перечислении новых сообщений") ret_value = -7
return ret_value
if __name__ == "__main__": bot_driver = None
try:
botdriver = simple_prepare() if botdriver is not None:
num_chats = simple_chat_count(botdriver)
if num_chats > 0:
num_select = 3 # число для выбора пользователем опции while int(num_select) >= 3 and int(num_select) <= 3:
num_select = input("3 - вывод последнего непрочитанного сообщения от каждого из адресатов\n")
#if int(num_select) == 1: обработка функции 1 #elif int(num_select) == 2: обработка функции 2
if int(num_select) == 3: #перечисление непрочитанных сообщений от контакта и группы
print("Введено значение 3: перечисление непрочитанных значений
от контакта и группы")###########
ret_value = show_new_messages(botdriver) if ret_value >= 0:
print("Функция выполнена успешно!)") else:
print("Функция поиска новых сообщений не выполнена
успешно!(")
else: # завершение приложения, если ни один из вариантов не
выбран
print("Нажмите любую клавишу для завершения приложения...") pass
finally:
if botdriver is not None: botdriver.quit()
print("Драйвер браузера и связанные соединения успешно закрыты!!") print("Приложение успешно закрыто.")