Czy możemy ułatwić dodawanie przepływów danych między odległymi częściami dużej bazy kodu?

10

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?

Vladimir Slepnev
źródło
Sposób, w jaki formułujesz swoje pytanie. Myślę, że masz na myśli przepływ danych w jednym procesie, bez komunikacji międzyprocesowej. Więc jaki widzisz problem, którego nie można rozwiązać za pomocą standardowych mechanizmów wysyłania / nasłuchiwania zdarzeń?
Doc Brown
Przemyślany przykład: wyobraź sobie, że głęboko w twoim systemie znajduje się kod, który wysyła użytkownikowi wiadomość tekstową. Otrzymujesz nowy wymóg, że tekst wiadomości powinien zależeć od bieżącego czasu w strefie czasowej użytkownika. Stos wywołań wygląda następująco: jakiś kod, który zna strefę czasową użytkownika, wywołuje metodę, która wywołuje metodę, która (... powtórzy 15 razy) wywołuje metodę, która generuje tekst wiadomości. Jest to prosty przykład według moich standardów, ponieważ wymaga komunikacji tylko w dół, ale wciąż musisz zmienić podpisy 15 metod, aby dokonać swojej trywialnej zmiany.
Vladimir Slepnev
Wydaje mi się, że pomocne może być jawne modelowanie przepływu danych i oddzielenie składników od przepływu danych. Niemiecki inżynier oprogramowania dużo pisze na ten temat, większość artykułów po niemiecku. Oto artykuł w języku angielskim o nim: geekswithblogs.net/theArchitectsNapkin/archive/2011/03/19/...
Doc Brown
Myślę, że singleton wewnętrzny interfejs API mógłby pomóc. Byłby dostępny w całej aplikacji i zawierałby całą logikę pobierania danych.
superM

Odpowiedzi:

1

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ą.

Senor Developer
źródło
Kolejki wiadomości mogą być przesadzone, ale wiadomości to idealny sposób na uruchamianie zdarzeń na całym forum. Java wykorzystuje Message Driven Beans (MDB), co powinno pozwolić Twojemu programowi na wysyłanie lub odbieranie „konwersacji” między sobą. Możesz to zrobić w ten sposób, aby uzyskać premię asynchroniczną.
Senor Developer
Dzięki za wskazówki! Zdecydowanie zastanawiam się, jak mógłby wyglądać język, gdyby został zaprojektowany od podstaw w celu obsługi wstrzykiwania zależności i podobnych wzorców.
Vladimir Slepnev
0

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.

Chris Travers
źródło
Dziękuję za odpowiedź! Wydaje mi się, że badania języka programowania mogłyby pomóc w rozwiązaniu tego problemu. Na przykład, jeśli kod odczytuje niektóre dane z globalnej bazy danych lub z ukrytych singletonów, może istnieć statyczna / deklaratywna gwarancja, których danych wymaga.
Vladimir Slepnev
-1

Jeśli użyjesz (lub zacytujesz) słowa

hairy flow of control

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 :-).

użytkownik127749
źródło
Dlaczego głosowanie negatywne? W cytacie brakowało wstępu, który dokładnie popiera mój pogląd: „(prawdopodobnie jest sklasyfikowany jako„ Antypattern ”lub„ Zapach kodowy ”i jako taki ma nazwę w odpowiednich kręgach, ale nie wiedziałbym, więc będę zostaw to bezimienne) ”
user127749,
2
To nie jest tak naprawdę odpowiedź na pytanie, prawdopodobnie jest to powód do przegłosowania
Daniel Gratzer
Pozwólcie, że sformułuję teraz pytanie: czy istnieje jakaś magiczna sztuczka, aby cofnąć bałagan kodu, który narusza jedną z najbardziej podstawowych zasad projektowania oprogramowania: KISS (to proste, głupie)? Sztuczka to nie magia, to albo programista, którego nie można wymienić, ponieważ zna on wszystkie nie tak oczywiste szczegóły (które zabiją firmę na dłuższą metę), albo restrukturyzuje bazę kodu. Niestety, wiele firm początkowo nie dba o odpowiedni projekt kodu lub nawet nie rozumie konsekwencji, a następnie musi przepisać swój kod co najmniej raz, wiele nawet przepisuje go wielokrotnie ...
user127749