Widziałem kilka polecających użycie kontenerów IoC w kodzie. Motywacja jest prosta. Weź następujący wstrzyknięty kod zależności:
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
}
W:
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>
(Powyższe jest oczywiście hipotetycznym przykładem C ++)
Chociaż zgadzam się, że upraszcza to interfejs klasy poprzez usunięcie parametru konstruktora zależności, myślę, że lekarstwo jest gorsze od choroby z kilku powodów. Po pierwsze, i to jest dla mnie duży, to powoduje, że twój program zależy od zewnętrznego pliku konfiguracyjnego. Jeśli potrzebujesz pojedynczego wdrożenia binarnego, po prostu nie możesz używać tego rodzaju kontenerów. Drugi problem polega na tym, że interfejs API jest teraz słabo i gorzej, ściśle napisany. Dowodem (w tym hipotetycznym przykładzie) jest argument ciągu do kontenera IoC i rzut na wynik.
Więc ... czy są inne korzyści z używania tego rodzaju pojemników, czy też nie zgadzam się z tymi, którzy zalecają pojemniki?