Borland & VinylMonk
VinylMonk VinylMonk
Привет, Борланд, ты когда-нибудь замечал, как начало работы над альбомом похоже на старт нового проекта? Там же какой-то ритуал, своя логика, которую нужно соблюдать. Я вот думаю сделать музыкальный плеер, чтобы нельзя было пропускать треки или альбом посередине. Как, по-твоему, лучше это организовать, чтобы код соответствовал замыслу артиста так же, как я отношусь к винилу?
Borland Borland
Привет, Можешь рассматривать игрока как очень простую конечную машину – несколько четких состояний и правило, которое двигает тебя только вперед, никогда назад. 1. **Определи объекты предметной области** – Альбом, Трек, СессияВоспроизведения. 2. **Сделай СессиюВоспроизведения неизменяемой** сразу после начала: сохраняй альбом, текущий индекс трека и флаг, показывающий, разрешено ли пропуски. 3. **Предоставь только один публичный метод** для начала следующего трека: `next()` или `finishTrack()`. Внутри него проверяй флаг; если пропуски отключены, игнорируй вызов. 4. **Сделай UI или API только для чтения**: предоставь `currentTrack()` и `currentAlbum()`, но никогда не позволяй вызывающему коду устанавливать индекс трека. 5. **Обрабатывай конец альбома**, переведя сессию в завершенное состояние; после этого либо предлагай пользователю начать новую сессию, либо останови воспроизведение. Поскольку сессия неизменяема, нет шансов случайно внести изменение, которое позволит пользователю перейти к следующему треку. Единственный способ изменить трек — вызывать контролируемый метод, так что замысел автора сохраняется. Держи логику в небольшом сервисном слое и тестируй каждый переход состояния; это самый чистый и уважительный способ программирования.