Я пытаюсь обдумать реализацию MVC с максимально возможной полезной абстракцией для автоматизированного модульного тестирования. В процессе я столкнулся с интересной загадкой: как и где мне объявить фиктивный объект для моей базы данных?
Вот что у меня есть.
- ContactView - это форма, которая реализует IContactView . Он обладает знанием IContactModel , поэтому может обновляться в ответ на уведомления о событиях от объекта модели.
- Контакт - это класс, который реализует IContactModel . Он инкапсулирует бизнес-правила для управления объектом, а также код для извлечения / обновления данных на уровне доступа к данным.
- ContactController - это класс, который реализует IContactController и обладает знаниями как IContactModel , так и IContactView .
- База данных - это класс, который реализует IDatabase и содержит методы для выбора, вставки, обновления и удаления данных в базе данных.
Для меня это сложная часть. Модельный объект должен знать, как взаимодействовать с IDatabase , чтобы он мог работать как с реальной базой данных, так и с фиктивным объектом. Проблема, с которой я столкнулся, заключается в том, чтобы предоставить ссылку на базу данных , не нарушая разделение проблем.
Я бы предпочел, чтобы представления и контроллеры не знали, как хранятся данные. Таким образом, если бы я решил сделать это позже, я мог бы поменять IDatabase на что-то вроде IJsonStore или IXmlStore, и мне нужно было только прикоснуться к модельным классам. Я не хочу, чтобы мои представления и контролеры делали какие-либо предположения о том, где и как хранятся данные.
Я вижу пару возможных решений, но я не уверен, что из них самое лучшее.
- Я могу объявить синглтон, который предоставляет публичное свойство, База данных (типа IDatabase ). Таким образом, модульные тесты могут установить для базы данных фиктивный объект, а производственный код - для производственной базы данных. Но это означает, что производственный код в какой-то момент должен был бы знать о IDatabase. Я полагаю, это неизбежно; но я надеюсь, что есть другое решение, которое предпочтительнее.
- Я могу изменить классы модели, чтобы сохранить ссылку на базу данных, взяв ее в конструкторе. Это кажется нежелательным просто потому, что это приводит к большому количеству дополнительного кода. И я вернулся к исходной точке: кто бы ни объявил, что экземпляр модели должен знать, какой IDatabase объект, который я хочу использовать.
Я уверен, что есть альтернативы, и я просто не знаю о них. Итак, я добавлю это: как бы вы, ребята, сделали это, и что вы видели, что это сработало?
Заранее спасибо.