Jestem dość pragmatykiem, ale moim głównym problemem jest to, że możesz pozwolić, ConfigBlockaby zdominowało to twoje projekty interfejsów w możliwie zły sposób. Gdy masz coś takiego:
explicit MyGreatClass(const ConfigBlock& config);
... bardziej odpowiedni interfejs może wyglądać tak:
MyGreatClass(int foo, float bar, const string& baz);
... w przeciwieństwie do zwykłego zbierania tych foo/bar/bazpól z ogromnych rozmiarów ConfigBlock.
Leniwy interfejs
Z drugiej strony, ten rodzaj projektu ułatwia zaprojektowanie stabilnego interfejsu dla twojego konstruktora, np. Jeśli w końcu potrzebujesz czegoś nowego, możesz po prostu załadować to do ConfigBlock(prawdopodobnie bez żadnych zmian kodu), a następnie wybieraj dowolne nowe rzeczy, których potrzebujesz, bez jakiejkolwiek zmiany interfejsu, tylko zmiana implementacji MyGreatClass.
Jest to więc w pewnym sensie plus i minus, który uwalnia cię od zaprojektowania bardziej przemyślanego interfejsu, który akceptuje tylko te dane wejściowe, których faktycznie potrzebuje. Stosuje sposób myślenia: „Po prostu daj mi tę ogromną kroplę danych, wybiorę z niej to, czego potrzebuję” w przeciwieństwie do czegoś bardziej podobnego: „Te precyzyjne parametry są tym, co ten interfejs musi działać”.
Są więc na pewno niektórzy profesjonaliści, ale ich zalety mogą być znacznie większe niż ich.
Sprzęganie
W tym scenariuszu wszystkie takie klasy tworzone z ConfigBlockinstancji mają swoje zależności wyglądające tak:

Może to być na przykład PITA, jeśli chcesz przeprowadzić test jednostkowy Class2na tym schemacie w izolacji. Być może będziesz musiał powierzchownie zasymulować różne ConfigBlockdane wejściowe zawierające odpowiednie pola, które Class2są zainteresowane, aby móc je przetestować w różnych warunkach.
W każdym nowym kontekście (test jednostkowy lub cały nowy projekt) każda taka klasa może stać się większym obciążeniem dla (ponownego) użytkowania, ponieważ ostatecznie musimy zawsze zabrać ConfigBlockze sobą na przejażdżkę i skonfigurować ją odpowiednio.
Możliwość ponownego użycia / wdrażania / testowalności
Zamiast tego, jeśli odpowiednio zaprojektujesz te interfejsy, możemy oddzielić je od siebie ConfigBlocki otrzymać coś takiego:

Jeśli zauważysz na powyższym schemacie, wszystkie klasy stają się niezależne (ich połączenia aferentne / wychodzące zmniejszają się o 1).
Prowadzi to do znacznie większej liczby niezależnych klas (przynajmniej niezależnych ConfigBlock), co może być o wiele łatwiejsze do (ponownego) użycia / przetestowania w nowych scenariuszach / projektach.
Teraz ten Clientkod jest tym, który musi polegać na wszystkim i złożyć wszystko razem. Ostatecznie obciążenie jest przenoszone do tego kodu klienta, aby odczytać odpowiednie pola z ConfigBlocki przekazać je do odpowiednich klas jako parametry. Jednak taki kod klienta jest generalnie wąsko zaprojektowany dla konkretnego kontekstu, a jego potencjał do ponownego użycia zwykle będzie zilch lub zamknięty (może to być mainfunkcja punktu wejścia aplikacji lub coś w tym rodzaju).
Z punktu widzenia możliwości ponownego użycia i testowania może to uczynić te klasy bardziej niezależnymi. Z punktu widzenia interfejsu dla tych, którzy używają twoich klas, może również pomóc w jawnym określeniu, jakich parametrów potrzebują, a nie tylko jednego, ConfigBlockktóry modeluje cały wszechświat pól danych wymaganych do wszystkiego.
Wniosek
Ogólnie rzecz biorąc, tego rodzaju projektowanie klasowe, które zależy od monolitu, który ma wszystko, co potrzebne, ma zwykle takie cechy. Ich zastosowanie, możliwość zastosowania, możliwość ponownego użycia, testowalność itp. Mogą w rezultacie ulec znacznej degradacji. Mogą jednak uprościć projekt interfejsu, jeśli spróbujemy go pozytywnie zakręcić. Od Ciebie zależy, czy zmierzysz zalety i wady i zdecydujesz, czy kompromisy są tego warte. Zazwyczaj bezpieczniej jest pomylić się z tego rodzaju projektami, w których wybieramy monolit z klas, które ogólnie mają na celu modelowanie bardziej ogólnego i szeroko stosowanego projektu.
Nie mniej ważny:
extern CodingBlock MyCodingBlock;
... jest to potencjalnie jeszcze gorsze (bardziej wypaczone?) pod względem cech opisanych powyżej niż podejście polegające na wstrzykiwaniu zależności, ponieważ ostatecznie łączy swoje klasy nie tylko ConfigBlocks, ale bezpośrednio z konkretnym jego wystąpieniem . To dodatkowo obniża możliwości zastosowania / wdrażania / testowalności.
Moja ogólna rada byłaby błędna przy projektowaniu interfejsów, które nie zależą od tego rodzaju monolitów w celu zapewnienia ich parametrów, przynajmniej dla najbardziej ogólnych klas, które projektujesz. I unikaj globalnego podejścia bez wstrzykiwania zależności, jeśli możesz, chyba że naprawdę masz bardzo silny i pewny powód, aby go nie unikać.