Я нахожусь в процессе разработки приложения, которое является частью большой части работы, в зависимости от других людей, чтобы создать API, который приложение может использовать для извлечения данных.
Пока я думал о том, как настроить этот проект и спроектировать архитектуру вокруг него, со мной что-то произошло, и я уверен, что многие люди были в подобных ситуациях.
Поскольку моя работа зависит от других людей, выполняющих свои задачи, и от тестового сервера, это замедляет работу с моей стороны.
Итак, вопрос:
Какова лучшая практика для создания тестовых репозиториев и классов, их реализации и отсутствия необходимости зависеть от изменения нескольких мест в коде для переключения между тестовыми классами и реальными репозиториями / собственными вызовами API.
Создайте следующий сценарий:
GetDataFromApiCommand *getDataCommand = [[GetDataFromApiCommand alloc]init];
getDataCommand.delegate = self;
[getDataCommand getData];
Как только данные доступны через API, «GetDataFromApiCommand» может использовать фактический API, но до тех пор набор фиктивных данных может быть возвращен при вызове [getDataCommand getData]
Может быть несколько таких случаев в разных местах кода, поэтому замена всех из них, где бы они ни находились, является медленным и болезненным процессом, который неизбежно приводит к тому, что один или два игнорируются.
В строго типизированных языках мы могли бы использовать внедрение зависимостей и просто изменить одно место.
В target-c можно реализовать фабричный шаблон, но разве это лучший путь для этого?
GetDataFromApiCommand *getDataCommand = [GetDataFromApiCommandFactory buildGetDataFromApiCommand];
getDataCommand.delegate = self;
[getDataCommand getData];
Какова наилучшая практика для достижения этого результата?
Поскольку это было бы наиболее полезно, даже если у вас есть действующий API, для запуска тестов или работы в автономном режиме, ApiCommands не обязательно должны быть заменены навсегда, но возможность выбрать «Хочу ли я использовать TestApiCommand или ApiCommand ".
Более интересно иметь возможность переключаться между:
Все команды тестовые
а также
Все команды используют живой API,
вместо того, чтобы выбирать их по одному, однако это также было бы полезно для тестирования одной или двух реальных команд API, смешивания их с тестовыми данными.
EDIT
Способ, который я выбрал для этого, - использовать фабричный шаблон.
Я настроил фабрику следующим образом:
@implementation ApiCommandFactory
+ (ApiCommand *)newApiCommand
{
// return [[ApiCommand alloc]init];
return [[ApiCommandMock alloc]init];
}
@end
И везде, где я хочу использовать класс ApiCommand:
GetDataFromApiCommand *getDataCommand = [ApiCommandFactory newApiCommand];
Когда требуется фактический вызов API, комментарии могут быть удалены, а макет может быть закомментирован.
Использование new в имени сообщения означает, что тот, кто когда-либо использует фабрику для получения объекта, несет ответственность за его освобождение (поскольку мы хотим избежать автоматического выпуска на iPhone).
Если требуются дополнительные параметры, завод должен учитывать их
то есть:
[ApiCommandFactory newSecondApiCommand:@"param1"];
Это будет очень хорошо работать и с репозиториями.