Wprowadzając zmiany w dużych systemach, często mam problem z tym, że jakiś element funkcjonalności musi uzyskać dane z innego elementu, ale znajdują się one w różnych częściach głębokiego i rozgałęzionego drzewa połączeń, prawdopodobnie przepływającego przez detektory zdarzeń, odroczone połączenia, itp. W ten sposób prosta zmiana może szybko się zmienić.
Powiązany cytat z posta na blogu Yossi Kreinina pod adresem http://www.yosefk.com/blog/i-want-a-struct-linker.html :
Masz jakąś strukturę danych, którą często przekazujesz. Wkrótce najcenniejszą rzeczą w strukturze nie są przechowywane przez nią dane, ale fakt, że są one dostępne przez całą owłosioną kontrolę.
Zmienne globalne to jeden klasyczny sposób pozwalający „wykrzyczeć” kod na odległe kody, ale wiadomo, że są problematyczne. Zmienne o dynamicznym zasięgu są bardziej ograniczonym sposobem, ale są również problematyczne.
Czy są jakieś badania języka programowania mające na celu rozwiązanie tego problemu? Czy możemy ułatwić dodawanie nieprzewidzianych przepływów danych do dużej bazy kodu przy jednoczesnym sprawdzeniu statycznym, łatwym testowaniu jednostek i innych korzyściach?
źródło
Odpowiedzi:
Masz na myśli CDI (wstrzykiwanie zależności kontekstowej) AKA IoC (inwersja kontroli). Java JSF i Spring Framework to tylko niektóre przykłady. ASP.NET MVC ma wtyczki takie jak Unity. JavaScript zaczyna organizować struktury przy użyciu bibliotek takich jak RequireJS, które mają zachowanie wstrzykiwania widoczne w wielu współczesnych frameworkach JS. To jest do okablowania lokalnych i zdalnych aplikacji.
W przypadku luźnego łączenia w sieciach firmy lubią korzystać z usług sieci Web przy użyciu SOAP, REST, AJAX lub zwykłego zdalnego wywoływania metod za pomocą RPC. W Javie możesz używać JAX-WS lub .NET WCF do budowania usług rozproszonych. Następnie ustawiasz je w szynie usługowej lub „przepływie danych” z dowolnego języka lub platformy jako klienta. Ruby, Python, Scala, Java, C #, ... cokolwiek.
Luźne sprzężenie umożliwia dzielenie i rozwiązywanie problemów, a usługi są często punktem wejścia do bazy danych do pobierania danych. Po drabinie mamy bestię o nazwie Kolejka wiadomości. Ta droga prowadzi do ram typu korporacyjnego i infrastrukturalnego.
Jeśli jednak Twój projekt nie wymaga sieci, istnieją takie języki, jak Scala, Akka, NodeJS itp., Które są przeznaczone do wysokiego przepływu danych w ramach jednej aplikacji. Współpracują również z niektórymi lub wszystkimi wcześniej wspomnianymi technologiami w przypadku złożonych projektów. Na przykład, Scala może być używana z usługami REST JAX-RS do pobierania rodzaju „globalnych danych” ze źródła danych i mieć sprężynę do wewnętrznego okablowania IoC. W narzędziach JBoss, .NET i GUI, takich jak MuleESB, dostępnych jest także wiele środowisk do wykonywania zadań biznesowych lub przepływu pracy. W fazie projektowania Eclipse i Netbeans umożliwiają przeciąganie i upuszczanie usług na ekranie wizualnym.
Wreszcie Java wciąż ma fasolę Singleton. Do dostosowywania metod w czasie wykonywania używaj ram proxy lub ramek do refleksji. Ale szczerze mówiąc, to jest rok 1999.
Jeśli wykonujesz tyle połączeń, aby wysłać użytkownikowi wiadomość na podstawie jego strefy czasowej, moim zdaniem istnieje prawdopodobnie 2-etapowy sposób na osiągnięcie tego samego efektu, który widzi użytkownik. Ale tak, ramy CDI są noszone przez istniejące języki, takie jak płaszcz, który daje im wszystkie elastyczne moce, o których wspomniałeś. Lubię to nazwać podświadomością mojego programu, płynnie zajmując się brudną pracą.
źródło
Najprostszym sposobem, aby to zrobić na dużą skalę, jest użycie interfejsu API do enkapsulacji danych. Może to być sklep NoSQL lub może to być kapsułkowany RDBMS (lub może to być zarówno w różnych czasach i miejscach w tej samej aplikacji - nie ma żadnego powodu, dla którego RDBMS nie może obsługiwać długoterminowo pamięć i baza danych NoSQL obsługująca krótkoterminową kontrolę stanu). Może to być nawet seria pojedynczych obiektów.
Struktury danych można następnie udostępnić w jakiejś neutralnej przestrzeni w nieco zarządzany sposób. Takie podejście przyjęliśmy w przypadku LedgerSMB (ale z kilkoma pół-globalnymi zmiennymi dla zasadniczo ukrytych singletonów, ale znowu nimi zarządzamy, wybraliśmy bezpośrednie ukrywanie obiektu, ponieważ ułatwiło to zarządzanie zmiennymi, ale potem są wszystkie 4).
Oczywiście każde podejście ma kompromisy i nie można obejść tych kompromisów. Kluczem jest przyjrzenie się kompromisom (zarządzanie vs wydajność vs. czystość kodu vs potencjalne pułapki kodowania) i podjęcie decyzji na podstawie tego, co jest najlepsze dla Twojej aplikacji.
źródło
Jeśli użyjesz (lub zacytujesz) słowa
zakładam, że twój kod naprawdę jest bałaganem. Powinieneś to upuścić natychmiast. Jeśli zastosujesz modularyzację / rozdzielenie problemów, nie ma czegoś takiego jak „włochaty przepływ kontroli”. W twoim kodzie po prostu brakuje prostoty, która jest również niezrozumiała, ponieważ odwoływałeś się do zmiennych globalnych :-).
źródło