В любом месте, где вам нужно значение времени выполнения для конструирования определенной зависимости, абстрактным Factory является решение.
Мой вопрос: почему многие источники предпочитают FactoryInterface над FactoryDelegate для реализации этого шаблона? Каковы преимущества и недостатки обоих решений?
Вот пример, чтобы понять, что я имею в виду
Если у вас есть Служба, которая нуждается в репозитории с определенным Контекстом, то конструктор службы требуется создать Factory для создания или доступа к его репозиторию.
Общим решением для этого является создание RepositoryFactoryInterface, как это.
public IRepositoryFactory {
IRepository Create(ContextInformation context);
}
public class MyService {
private IRepositoryFactory repositoryFactory;
public MyService(IRepositoryFactory repositoryFactory)
{
this.repositoryFactory = repositoryFactory:
}
public void DoSomeService()
{
ContextInformation context = ....;
IRepository repository = this.repositoryFactory.Create(context);
repository.Load(...);
...
repository.Save(...);
}
}
Вам также необходимо реализовать интерфейс IRepositoryFactory.
public MyEf4RepositoryFactory : IRepositoryFactory
{
IRepository Create(ContextInformation context)
{
return new MyEf4Repository(context);
}
}
... и использовать его в приложении
public void main()
{
IRepositoryFactory repoFactory = new MyEf4RepositoryFactory();
IService service = new MyService(repoFactory);
service.DoSomeService();
}
----- Конец основного решения ------
Вместо RepositoryFactoryInterface вы можете сделать то же самое с factorydelegate, для которого требуется меньше кодирования.
public class MyService {
private Func<ContextInformation, IRepository> repositoryFactory;
public MyService(Func<ContextInformation, IRepository> repositoryFactory)
{
this.repositoryFactory = repositoryFactory:
}
public void DoSomeService()
{
ContextInformation context = ....;
IRepository repository = this.repositoryFactory(context);
repository.Load(...);
...
repository.Save(...);
}
}
... и использовать его в приложении
public void main()
{
IService service = new MyService(context => new MyEf4Repository(context));
service.DoSomeService();
}
По моему мнению, factorydelegate context => new MyEf4Repository(context)
намного компактнее, чем
объявление и реализация интерфейса IRepositoryFactory
и MyEf4RepositoryFactory
.
Для этого должна быть причина, и я хочу знать почему.
Вот один пример источника, который использует интерфейс aproach: ответ на is-there-a-pattern-for-initialization-objects-created-via-a-di-container
[Обновление] Спустя 15 месяцев после того, как я задал этот вопрос и получил больше опыта работы с java-универсалами, я передумал: теперь я предпочитаю интерфейсы над делегатами. Но я не могу сказать, почему. Это просто чувство. Может быть, потому, что я больше привык к этому?