Сервісно-орієнтована архітектура¶
Gaphor має сервіс-орієнтовану архітектуру. Що це означає? Ну, Gaphor побудований як набір маленьких острівців (сервісів). Кожен острівець забезпечує певну частину функціональності. Наприклад, ми використовуємо окремі сервіси для завантаження/збереження моделей, забезпечення структури меню та роботи з системою скасування.
Ми визначаємо сервіси як точки входу в pyproject.toml. За допомогою точок входу програми можуть реєструвати функціональність для певних цілей. Ми також групуємо точки входу у групи точок входу. Наприклад, ми використовуємо групу точок входу console_scripts для запуску програми з командного рядка.
Послуги¶
Gaphor моделюється навколо концепції послуг. Кожну послугу можна зареєструвати в програмі, а потім нею можуть користуватися інші служби або інші об’єкти, що знаходяться в програмі.
Кожна служба повинна реалізовувати інтерфейс служби. Цей інтерфейс визначає один метод:
shutdown(self)
Викликається, коли послугу потрібно очистити.
Ми дозволяємо кожній службі визначати власні методи, якщо послугу також реалізовано.
Послуги мають бути визначені як точки входу у файлі pyproject.toml.
Зазвичай, сервіс виконує певну роботу у фоновому режимі. Сервіси також можуть надавати дії, які можуть бути викликані користувачами. Наприклад, комбінація клавіш Ctrl-z (скасувати) реалізована за допомогою сервісу UndoManager.
Послуга також може залежати від інших служб. Ініціалізація служби усуває ці залежності. Щоб визначити залежність служби, просто додайте її до конструктора за її іменем, визначеним у точці входу:
class MyService(Service):
def __init__(self, event_manager, element_factory):
self.event_manager = event_manager
self.element_factory = element_factory
event_manager.subscribe(self._element_changed)
def shutdown(self):
self.event_manager.unsubscribe(self._element_changed)
@event_handler(ElementChanged)
def _element_changed(self, event):
Сервіси, які виставляють дії, також повинні успадковувати інтерфейс ActionProvider. Цей інтерфейс не вимагає реалізації жодних додаткових методів. Методи дій повинні мати анотацію @action.
Приклад: ElementFactory¶
Гарним прикладом використовуваної служби є ElementFactory. Це одна з основних послуг.
Коли відбувається важлива подія, наприклад, створюється або знищується елемент, ця подія випромінюється. Потім ми використовуємо обробник подій для ElementFactory, який зберігає сигнали додавання/видалення у системі скасування. Іншим прикладом подій, які генеруються, є події для Element`. Ці класи, або, точніше, властивості, надсилають сповіщення щоразу, коли змінюється їхній стан.
Точки входу¶
Gaphor використовує основну групу :refentry point <https://packaging.python.org/en/latest/specifications/entry-points/> під назвою gaphor.services.
Послуги використовуються для виконання основних функцій програми, одночасно розбиваючи функції на окремі компоненти. Наприклад, фабрика елементів і диспетчер скасування є послугами.
Плагіни також можуть бути створені для розширення функціональності Gaphor за межі основної функціональності в якості надбудови. Наприклад, можна створити плагін для підключення даних моделі до інших додатків. Плагіни також визначаються як сервіси. Наприклад, новий плагін для експорту XMI може бути визначений наступним чином у файлі pyproject.tml:
[tool.poetry.plugins."gaphor.services"]
"xmi_export" = "gaphor.plugins.xmiexport:XMIExport"
Інтерфейси¶
Кожна служба (і плагін) має реалізовувати інтерфейс gaphor.abc.Service:
Іншим більш спеціалізованим сервісом, який також успадковується від gaphor.abc.Service, є сервіс UI Component. Служби, які використовують цей інтерфейс, використовуються для визначення вікон та функціональності інтерфейсу користувача. UI-компонент має реалізовувати інтерфейс gaphor.ui.abc.UIComponent:
- class gaphor.ui.abc.UIComponent[source]¶
Компонент інтерфейсу користувача.
- abstractmethod close()[source]¶
Закрийте компонент інтерфейсу користувача.
Компонент може вирішити приховати або знищити компоненти інтерфейсу користувача.
Зазвичай, сервіс та компонент інтерфейсу хочуть представити користувачеві деякі дії за допомогою пунктів меню. Кожен сервіс та компонент інтерфейсу може рекламувати дії, реалізувавши інтерфейс gaphor.abc.ActionProvider: