Próbuję dowiedzieć się, kiedy użyć rejestru DIC / IoC do konfiguracji mojego oprogramowania i kiedy korzystać z fabryk, wraz z uzasadnieniem każdego z tych podejść.
Używam StructureMap jako mojego kontenera DI (DIC), który można łatwo skonfigurować za pomocą rejestrów. W DIC praktycznie wszystkie zarejestrowane obiekty są statyczne w tym sensie, że nie muszę zmieniać / wymieniać żadnej implementacji / instancji w czasie wykonywania, gdy DIC jest skonfigurowany i są one skonfigurowane w DIC jako singletony. Ponieważ jednak moje oprogramowanie (SW) będzie działać na różnych urządzeniach , muszę wybrać rejestr specyficzny dla urządzenia w zależności od urządzenia, na którym działa mój SW, aby odpowiednio skonfigurować sprzęt.
Ponieważ konstrukcja niektórych moich obiektów wymaga odczytu w plikach konfiguracyjnych, używam fabryk, aby zwrócić te instancje do DIC, aby oddzielić odczyt konfiguracji od stworzenia obiektu. Zarejestrowałem gettery fabryczne w DIC dla odpowiednich typów wtyczek.
Powiedzmy teraz, że mam typ wtyczki IMotor
z konkretnymi typami Motor1
i Motor2
które powinny być obsługiwane przez fabrykę. Są teraz dwa sposoby, w jakie mogę zdecydować, jak skonfigurować urządzenie:
- Mijam informacje o urządzeniu, że SW jest uruchomiony na do
MotorFactory
i zwraca odpowiedni silnik, alboMotor1
alboMotor2
. W tym przypadku logika podejmowania decyzji leży w fabryce. - Konfiguruję DIC zgodnie z urządzeniem, na którym działa, i tworzę dwie fabryki
Motor1Factory
orazMotor2Factory
, gdzie jedna tworzy,Motor1
a drugaMotor2
. W tym przypadku chciałbym mają różne wpisy rejestru dlaIMotor
w rejestrach dla danego urządzenia, które wykorzystują alboMotor1Factory
alboMotor2Factory
.
Teraz moje pytanie brzmi: która z tych dwóch metod jest lepsza i dlaczego? Wydaje mi się, że pierwszy przypadek nie jest prosty i skomplikowany, ponieważ rozszerzam logikę, która decyduje o tym, jaki typ utworzyć w całej bazie kodu. Podczas gdy w drugim przypadku skutecznie zwiększam liczbę fabryk w moim kodzie, ponieważ będę potrzebował fabryki (prawie) każdego konkretnego typu. Staje się dla mnie jeszcze bardziej mylące, gdy do mieszanki dodawane są abstrakcyjne fabryki.
Więc jeszcze raz: kiedy powinienem skorzystać z jednej lub drugiej metody? I co ważniejsze: jakie są dobre wskaźniki przy podejmowaniu decyzji, którą drogą wybrać?
źródło
Odpowiedzi:
Jeśli użyjesz obu, wybiorę coś prostego:
źródło
Fabryki abstrakcyjne są używane, gdy masz obiekty powiązane w hierarchii, która musi się różnić. Nie widzę tego tutaj.
Widzę, że zastanawiasz się, czy fabryka powinna wybrać silnik, czy też DIC powinien wybrać fabrykę produkującą dany silnik.
Trudno wybrać dokładnie, ponieważ fabryka i DIC robią bardzo podobne rzeczy. Różnica polega na tym, że fabryka koncentruje się na konkretnym problemie, a DIC jest bardziej ogólny.
Wszystko sprowadza się do pytania: czy potrzebujesz kodu specyficznego dla tego problemu, który pojawi się w fabryce? Czy jest to bardziej ogólne jak odczytanie szczegółów konfiguracji z pliku?
Należy pamiętać, że podczas wyboru mogą być tylko między
Motor1
iMotor2
dzisiaj, jutro może istniećMotor3
. Wybierz projekt, który możnaMotor3
łatwo dodać.źródło
Oddzieliłbym logikę „którego silnika użyć” do specjalnej fabryki o nazwie Builder (wzorzec) i użyłem kontenera IOC dla obu silników jako szczegółów implementacyjnych konstruktora.
Z reguły:
źródło