Диаграммы классов - gogafefe/StAlGoLM GitHub Wiki
Диаграммы построены по текущему исходному коду проекта. Добавлять новые классы для их создания не требуется: диаграмма описывает уже существующую архитектуру.
Обозначения связей:
-
A <|-- B— классBнаследуется отA; -
A *-- B— композиция: объектAвладеет объектом или набором объектовB; -
A --> B— направленная ассоциация; -
A ..> B— зависимость:AиспользуетB.
В клиентской части собственный класс проекта один — MainWindow. Он наследуется от QMainWindow, создаёт TCP-сокет и элементы интерфейса Qt. Через сокет окно отправляет текстовые команды серверу и получает ответы.

Исходник Mermaid диаграммы клиента
classDiagram
direction LR
class QMainWindow
class QTcpSocket
class QLineEdit
class QSpinBox
class QPushButton
class QComboBox
class QButtonGroup
class QPlainTextEdit
class QLabel
class MainWindow {
-QTcpSocket socket
-QLineEdit editHost
-QSpinBox spinPort
-QLineEdit editLogin
-QLineEdit editPassword
-QLineEdit editEmail
-QComboBox comboTask
-QSpinBox spinTaskNum
-QButtonGroup optGroup
-QLineEdit editAnswer
-QPlainTextEdit logView
-QLabel lblUser
-bool loggedIn
-int activeTaskType
+MainWindow(parent)
-buildUi()
-sendCommand(command)
-log(who, text)
-setConnectionState(connected)
-setRadiosEnabled(on)
-resetTaskState()
-onConnectClicked()
-onConnected()
-onDisconnected()
-onReadyRead()
-onSocketErrorOccurred(error)
-onRegClicked()
-onAuthClicked()
-onLogoutClicked()
-onWhoamiClicked()
-onGetTaskClicked()
-onAnswerClicked()
-onMystatsClicked()
}
QMainWindow <|-- MainWindow : наследование
MainWindow *-- QTcpSocket : TCP-соединение
MainWindow *-- QLineEdit : поля ввода
MainWindow *-- QSpinBox : числовые поля
MainWindow *-- QPushButton : команды интерфейса
MainWindow *-- QComboBox : выбор задания
MainWindow *-- QButtonGroup : варианты ответа
MainWindow *-- QPlainTextEdit : журнал обмена
MainWindow *-- QLabel : состояние пользователя
Серверная часть разделена на приём TCP-соединений, хранение состояния сессии, разбор команд, работу с базой данных и генерацию заданий. MyTcpServer и DatabaseManager реализованы как одиночки: получить их экземпляры можно через getInstance(), а копирование запрещено.
CommandFunctions и TaskGenerators на диаграмме отмечены стереотипом module. Это не классы C++, а логические группы свободных функций из файлов server_functions.* и task1.*–task4.*. Такое обозначение позволяет показать важные зависимости, не выдавая функции за реально существующие классы.

Исходник Mermaid диаграммы сервера
classDiagram
direction LR
namespace Qt {
class QObject
class QTcpServer
class QTcpSocket
class QSqlDatabase
}
class MyTcpServer {
-QTcpServer mTcpServer
-Map sessions
-Map buffers
-MyTcpServer(parent)
-MyTcpServer(copy) deleted
+getInstance() MyTcpServer*
+~MyTcpServer()
+slotNewConnection()
+slotClientDisconnected()
+slotServerRead()
}
class UserSession {
+QString login
+QString email
+UserRole role
+QTcpSocket msock
+int currentTaskType
+int currentTaskNum
+int currentCorrectAnswer
}
class DatabaseManager {
-QSqlDatabase db
-DatabaseManager()
-DatabaseManager(copy) deleted
-initDatabase()
-initStatisticTables()
-updateLastAuth(login)
+getInstance() DatabaseManager*
+regUser(login, password, email, role) bool
+authUserWithRole(login, password) UserRole
+getUserRole(login) UserRole
+getUserEmail(login) QString
+deleteUser(login) bool
+updateUserRole(login, role) bool
+userExists(login) bool
+getAllUsers() UserInfo[]
+getStats() UserStats
+createStatisticRows(login) bool
+updateStatistic(login, task, problem, delta) bool
+getStatisticRow(login, task) int[]
+deleteStatisticRows(login) bool
}
class UserRole {
<<enumeration>>
ROLE_USER
ROLE_MODERATOR
ROLE_ADMIN
ROLE_ERR
}
class UserInfo {
+QString login
+QString email
+UserRole role
+QString registeredAt
+QString lastAuth
}
class UserStats {
+int totalUsers
+int newUsersMonth
+int activeUsersMonth
}
class CommandFunctions {
<<module>>
+processCommand(command, session) QString
+cmd_reg(parts) QString
+cmd_auth(parts, session) QString
+cmd_logout(session) QString
+cmd_whoami(session) QString
+cmd_del(parts, session) QString
+cmd_role(parts, session) QString
+cmd_users(session) QString
+cmd_stats(session) QString
+cmd_help() QString
+cmd_task(type, number, session) QString
+cmd_answer(answer, session) QString
+cmd_mystats(parts, session) QString
}
class TaskGenerators {
<<module>>
+task1_generate(number) Task1Problem
+task2_generate(number) Task2Problem
+task3_generate(number) Task3Problem
+task4_generate(number) Task4Problem
}
class Task1Problem {
+QString text
+int correctAnswer
}
class Task2Problem {
+QString text
+int correctAnswer
}
class Task3Problem {
+QString text
+int correctAnswer
}
class Task4Problem {
+QString text
+int correctAnswer
}
QObject <|-- MyTcpServer : наследование
MyTcpServer *-- QTcpServer : владеет
QTcpServer ..> QTcpSocket : принимает соединения
MyTcpServer *-- UserSession : хранит сессии
UserSession --> QTcpSocket : сокет клиента
UserSession --> UserRole : роль
MyTcpServer ..> CommandFunctions : передаёт команды
CommandFunctions ..> UserSession : изменяет
CommandFunctions ..> DatabaseManager : использует
CommandFunctions ..> TaskGenerators : запрашивает задания
DatabaseManager *-- QSqlDatabase : соединение SQLite
DatabaseManager ..> UserRole : использует
DatabaseManager ..> UserInfo : возвращает
DatabaseManager ..> UserStats : возвращает
TaskGenerators ..> Task1Problem : создаёт
TaskGenerators ..> Task2Problem : создаёт
TaskGenerators ..> Task3Problem : создаёт
TaskGenerators ..> Task4Problem : создаёт
- Клиент отвечает только за интерфейс и обмен командами по TCP; вычисления заданий и работа с базой находятся на сервере.
- Сервер хранит отдельную
UserSessionдля каждого подключённого клиента. - Разбор команд связывает сетевой слой с базой данных и генераторами четырёх типов заданий.
- Реализованный вариант № 3 не добавляет новый класс: он использует существующую структуру
Task3Problemи функциюtask3_generate().
Исходники Mermaid приведены выше; изображения PNG содержат редактируемые данные draw.io.