Я видел несколько рекомендованных к использованию контейнеров IoC в коде. Мотивация проста. Возьмите следующий введенный код зависимости:
class UnitUnderTest
{
std::auto_ptr<Dependency> d_;
public:
UnitUnderTest(
std::auto_ptr<Dependency> d = std::auto_ptr<Dependency>(new ConcreteDependency)
) : d_(d)
{
}
};
TEST(UnitUnderTest, Example)
{
std::auto_ptr<Dependency> dep(new MockDependency);
UnitUnderTest uut(dep);
//Test here
}
В:
class UnitUnderTest
{
std::auto_ptr<Dependency> d_;
public:
UnitUnderTest()
{
d_.reset(static_cast<Dependency *>(IocContainer::Get("Dependency")));
}
};
TEST(UnitUnderTest, Example)
{
UnitUnderTest uut;
//Test here
}
//Config for IOC container normally
<Dependency>ConcreteDependency</Dependency>
//Config for IOC container for testing
<Dependency>MockDependency</Dependency>
(Выше приведен пример гипотетического C ++)
Хотя я согласен, что это упрощает интерфейс класса, удаляя параметр конструктора зависимостей, я думаю, что лекарство хуже, чем болезнь, по нескольким причинам. Во-первых, и это очень важно для меня, это делает вашу программу зависимой от внешнего файла конфигурации. Если вам нужно одиночное двоичное развертывание, вы просто не сможете использовать эти типы контейнеров. Вторая проблема заключается в том, что API теперь слабый и худший, строго типизированный. Доказательством (в этом гипотетическом примере) является строковый аргумент контейнера IoC и приведение к результату.
Итак ... есть ли другие преимущества использования таких контейнеров или я просто не согласен с теми, кто рекомендует контейнеры?