Я пишу много кода, который включает в себя три основных шага.
- Получить данные откуда-то.
- Преобразуйте эти данные.
- Положите эти данные куда-нибудь.
Я обычно заканчиваю тем, что использую три типа классов - вдохновленные их соответствующими шаблонами дизайна.
- Фабрики - построить объект из какого-то ресурса.
- Посредники - использовать фабрику, выполнить трансформацию, затем использовать командира.
- Командиры - разместить эти данные где-то еще.
Мои классы, как правило, довольно малы, часто представляют собой один (общедоступный) метод, например, получение данных, преобразование данных, выполнение работы, сохранение данных. Это приводит к увеличению числа классов, но в целом работает хорошо.
Когда я прихожу на тестирование, я бьюсь о том, чтобы в конечном итоге я получал тесно связанные тесты. Например;
- Factory - читает файлы с диска.
- Commander - записывает файлы на диск.
Я не могу проверить одно без другого. Я мог бы написать дополнительный «тестовый» код для чтения и записи на диск, но потом я повторяюсь.
Глядя на .Net, класс File использует другой подход, он объединяет обязанности (моей) фабрики и командира вместе. Он имеет функции для создания, удаления, существования и чтения всего в одном месте.
Должен ли я последовать примеру .Net и объединить - особенно при работе с внешними ресурсами - мои занятия вместе? Код все еще связан, но он более намеренный - это происходит в исходной реализации, а не в тестах.
Является ли моя проблема здесь в том, что я применил принцип единой ответственности несколько слишком усердно? У меня есть отдельные классы, ответственные за чтение и запись. Когда я мог иметь комбинированный класс, который отвечает за работу с конкретным ресурсом, например системным диском.
Looking at .Net, the File class takes a different approach, it combines the responsibilities (of my) factory and commander together. It has functions for Create, Delete, Exists, and Read all in one place.
- Обратите внимание, что вы связываете «ответственность» с «делом». Ответственность больше похожа на «проблемную область». Класс File отвечает за выполнение файловых операций.
File
библиотеке из C # является то, что, насколько мы знаем, File
класс может быть просто фасадом, помещающим все файловые операции в одном месте - в классе, но может внутренне использовать классы чтения / записи, аналогичные вашим, что на самом деле содержат более сложную логику для обработки файлов. Такой класс (the File
) все еще будет придерживаться SRP, потому что процесс фактической работы с файловой системой будет абстрагирован за другим уровнем - скорее всего, с объединяющим интерфейсом. Не сказать, что это так, но это может быть. :)