Ten sam podstawowy problem, który często napotykasz z programowaniem obiektowym, regułami stylu i wszystkim innym. Możliwe jest - bardzo powszechne - zbytnie abstrakowanie i dodawanie zbyt dużej liczby pośrednich oraz generalne stosowanie dobrych technik w nadmiernych i niewłaściwych miejscach.
Każdy zastosowany wzór lub inny konstrukt powoduje złożoność. Abstrakcja i pośrednie rozpraszają informacje, czasami usuwając nieistotne szczegóły z drogi, ale równie często czasami utrudniają dokładne zrozumienie, co się dzieje. Każda zastosowana reguła zapewnia elastyczność, wykluczając opcje, które mogą być najlepszym rozwiązaniem.
Chodzi o to, aby napisać kod, który wykonuje zadanie i jest solidny, czytelny i łatwy w utrzymaniu. Jesteś programistą, a nie budowniczym wieży z kości słoniowej.
Ważne linki
http://thedailywtf.com/Articles/The_Inner-Platform_Effect.aspx
http://www.joelonsoftware.com/articles/fog0000000018.html
Prawdopodobnie najprostszą formą wstrzykiwania zależności (nie śmiać się) jest parametr. Kod zależny jest zależny od danych, a dane te są wprowadzane poprzez przekazanie parametru.
Tak, to głupie i nie odnosi się do zorientowanego obiektowo punktu wstrzykiwania zależności, ale programista funkcjonalny powie ci, że (jeśli masz funkcje pierwszej klasy) jest to jedyny rodzaj zastrzyku zależności, którego potrzebujesz. Chodzi o to, aby wziąć trywialny przykład i pokazać potencjalne problemy.
Weźmy tę prostą tradycyjną funkcję - składnia C ++ nie ma tutaj znaczenia, ale muszę to jakoś przeliterować ...
void Say_Hello_World ()
{
std::cout << "Hello World" << std::endl;
}
Mam zależność, którą chcę wyodrębnić i wstrzyknąć - tekst „Hello World”. Wystarczająco łatwe...
void Say_Something (const char *p_text)
{
std::cout << p_text << std::endl;
}
Jak to jest bardziej nieelastyczne niż oryginał? Co jeśli zdecyduję, że wyjście powinno być Unicode. Prawdopodobnie chcę zmienić std :: cout na std :: wcout. Ale to oznacza, że moje struny muszą być wchar_t, a nie char. Albo każdy program wywołujący musi zostać zmieniony, albo (bardziej rozsądnie), stara implementacja zostaje zastąpiona adapterem, który tłumaczy ciąg znaków i wywołuje nową implementację.
To prace konserwacyjne, które nie byłyby potrzebne, gdybyśmy zachowali oryginał.
A jeśli wydaje się to trywialne, spójrz na tę rzeczywistą funkcję z Win32 API ...
http://msdn.microsoft.com/en-us/library/ms632680%28v=vs.85%29.aspx
To 12 „zależności”, z którymi trzeba sobie poradzić. Na przykład, jeśli rozdzielczości ekranu stają się naprawdę ogromne, być może będziemy potrzebować 64-bitowych wartości współrzędnych - i innej wersji CreateWindowEx. I tak, wciąż kręci się starsza wersja, która prawdopodobnie została zmapowana do nowszej wersji za kulisami ...
http://msdn.microsoft.com/en-us/library/ms632679%28v=vs.85%29.aspx
Te „zależności” nie są tylko problemem dla pierwotnego programisty - każdy, kto korzysta z tego interfejsu, musi sprawdzić, jakie są zależności, jak są określone i co oznaczają, i dowiedzieć się, co zrobić dla swojej aplikacji. To tutaj słowa „rozsądne wartości domyślne” mogą znacznie uprościć życie.
Zastrzykiwanie zależności obiektowych zasadniczo nie różni się. Pisanie klasy jest narzutem, zarówno w tekście kodu źródłowego, jak i w czasie programowania, a jeśli klasa ta jest zapisywana w celu dostarczania zależności zgodnie z niektórymi specyfikacjami obiektów zależnych, wówczas obiekt zależny jest zablokowany do obsługi tego interfejsu, nawet jeśli jest taka potrzeba zastąpić implementację tego obiektu.
Nic z tego nie powinno być interpretowane jako twierdzenie, że wstrzykiwanie zależności jest złe - wręcz przeciwnie. Ale każdą dobrą technikę można zastosować nadmiernie i w niewłaściwym miejscu. Podobnie jak nie każdy ciąg musi zostać wyodrębniony i przekształcony w parametr, nie każde zachowanie niskiego poziomu musi zostać wyodrębnione z obiektów wysokiego poziomu i przekształcone w zależność do wstrzykiwania.