Глава 17 · Архитектура
Архитектура TicTacToeApp
app.root, а не class TicTacToeApp(tk.Tk) — та же композиция, что и в главе 16.
app HAS-A root — не наследование от Tk
Композиция против наследования
Возможно, но не нужно
class TicTacToeApp(tk.Tk):
def __init__(self):
super().__init__()
...
Как в главе 16
class TicTacToeApp:
def __init__(self, root):
self.root = root
...
Что использовать сегодня: Наследование от
tk.Tk технически работает, но не нужно и не согласуется с тем, как строились приложения в главе 16. app.root (композиция, «HAS-A») — тот же паттерн, что и у Tip Calculator Pro и редактора заметок.Объектный граф приложения
Домен против UI — разделение ответственности
| Чистая доменная логика (без Tkinter) | UI-логика (внутри TicTacToeApp) |
|---|---|
| find_winner(board) | on_cell_click / attempt_move — вызывает домен, потом render |
| is_draw(board) | on_cell_enter / on_cell_leave — превью |
| index → row/column | render() — рисует виджеты ИЗ модели (state) |
| new_round() / new_match() — жизненный цикл |
Проверка «можно ли протестировать без окна?»
Хороший тест архитектуры: если для проверки функции обязательно открывать окно Tkinter — это, вероятно, UI-логика. Если можно вызвать её с обычными списком/строкой и получить результат — это доменная логика, и её МОЖНО было бы вынести в отдельный модуль.
Практика: собираем объектный граф TicTacToeApp
Модуль tkinter открывает нативное окно Python — выполните локально в VS Code, PyCharm или Jupyter
Практика выполняется локально