Постановка задачи и проектирование
Постановка задачи и проектирование
Вы изучили весь арсенал Python: переменные, управляющие конструкции, функции, модули, файлы, исключения и классы. Пришло время применить всё вместе в реальном проекте. Этот модуль — финальный: мы построим консольную телефонную книгу с сохранением данных между сессиями.
Что мы строим
Телефонная книга — программа командной строки, которая умеет:
- Добавить контакт (имя, телефон, опционально email)
- Найти контакт по имени
- Показать все контакты
- Удалить контакт
- Сохранять данные в JSON-файл
- Загружать данные при запуске
Проект небольшой, но включает всё: классы, файлы, обработку ошибок, модульную структуру, пользовательский интерфейс.
Шаг 1: понять требования
Перед написанием кода — ответить на вопросы:
Данные: что хранит один контакт?
- Имя (строка, обязательное)
- Телефон (строка, обязательное) — строка, потому что телефоны могут начинаться с
+или0 - Email (строка, опциональное)
Хранилище: где живут все контакты?
- Список контактов в памяти
- При старте загружаем из JSON
- После каждого изменения — сохраняем в JSON
Интерфейс: как пользователь взаимодействует?
- Меню в цикле: пользователь вводит команду, программа выполняет и снова показывает меню
- Graceful выход при вводе
quitили0
Шаг 2: выделить сущности (классы)
Хороший вопрос для дизайна: «что является объектом в этой предметной области?»
Contact — один контакт. Хранит данные, умеет представлять себя строкой.
AddressBook — коллекция контактов. Умеет добавлять, искать, удалять, загружать и сохранять.
ContactNotFoundError — собственное исключение для ситуации «контакт не найден».
Шаг 3: интерфейс классов (API)
Проектирование сверху вниз: сначала определяем, как классы будут использоваться, потом реализуем:
# Так будет выглядеть использование:
book = AddressBook("contacts.json") # загружает данные из файла
contact = Contact("Алиса", "+7 (999) 123-45-67", email="alice@example.com")
book.add(contact)
found = book.find("Алиса") # возвращает Contact или выбрасывает ContactNotFoundError
print(found) # Алиса: +7 (999) 123-45-67
book.delete("Алиса")
# book.delete("Никто") # ContactNotFoundError
all_contacts = book.all() # список всех Contact
book.save() # сохранить в файл
Это контракт — то, что классы должны обеспечить. Реализация деталей — внутреннее дело класса.
Шаг 4: структура файлов
phonebook/
contact.py — класс Contact и ContactNotFoundError
address_book.py — класс AddressBook
cli.py — функции CLI (меню, ввод/вывод)
main.py — точка входа: запуск программы
contacts.json — данные (создаётся автоматически)
Разделение по файлам — не обязательное требование для такого проекта, но хорошая привычка. Каждый файл отвечает за одну вещь.
Зачем проектировать перед кодом
Кажется, что это лишний шаг — можно же сразу писать? Но небольшое время на проектирование экономит гораздо больше на переработке:
- Ясно, что делает каждая часть системы
- Легче тестировать — каждый класс независим
- Легче расширять — добавить поиск по телефону = один новый метод в
AddressBook
В следующем уроке создадим файловую структуру проекта и рассмотрим, как классы из разных файлов работают вместе.