Kontener DI / IoC a fabryki: gdzie mam skonfigurować aplikację i dlaczego?

9

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 IMotorz konkretnymi typami Motor1i Motor2które powinny być obsługiwane przez fabrykę. Są teraz dwa sposoby, w jakie mogę zdecydować, jak skonfigurować urządzenie:

  1. Mijam informacje o urządzeniu, że SW jest uruchomiony na do MotorFactoryi zwraca odpowiedni silnik, albo Motor1albo Motor2. W tym przypadku logika podejmowania decyzji leży w fabryce.
  2. Konfiguruję DIC zgodnie z urządzeniem, na którym działa, i tworzę dwie fabryki Motor1Factoryoraz Motor2Factory, gdzie jedna tworzy, Motor1a druga Motor2. W tym przypadku chciałbym mają różne wpisy rejestru dla IMotorw rejestrach dla danego urządzenia, które wykorzystują albo Motor1Factoryalbo Motor2Factory.

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ć?

packoman
źródło
2
Który sposób jest prostszy? Czy korzyści z bardziej złożonego podejścia przewyższają koszty dodatkowej złożoności?
Robert Harvey,

Odpowiedzi:

2

Jeśli użyjesz obu, wybiorę coś prostego:

  • DI / IoC: dla każdej konfiguracji, która nie zmieni się w czasie wykonywania.
  • Fabryka: do tworzenia instancji obiektów w czasie wykonywania, która zależy od parametrów wejściowych środowiska wykonawczego. Instancje fabryczne są wstrzykiwane przez pojemnik DI.
Walfrat
źródło
1

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 Motor1i Motor2dzisiaj, jutro może istnieć Motor3. Wybierz projekt, który można Motor3łatwo dodać.

candied_orange
źródło
0

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:

  • potrzebujesz fabryki (lub konstruktora), jeśli musisz utworzyć wiele dynamicznych obiektów klasy / interfejsu. (tj. dla każdego produkowanego samochodu musisz stworzyć jeden nowy silnik)
  • jeśli potrzebujesz tylko jednego statycznego wystąpienia klasy, ioc / di może wykonać zadanie za Ciebie (tj. potrzebujesz tylko jednego statycznego wystąpienia usługi płatności i jednego statycznego wystąpienia MotorBuilderService)
k3b
źródło