Possiamo semplificare l'aggiunta di flussi di dati tra parti distanti di una base di codice di grandi dimensioni?


10

Quando apporto modifiche a sistemi di grandi dimensioni, spesso incontro il problema che alcune funzionalità necessitano per ottenere alcuni dati da un altro pezzo, ma si trovano in parti diverse di un albero delle chiamate profondo e ramificato, che può fluire attraverso listener di eventi, chiamate differite, ecc. In questo modo un semplice cambiamento può diventare rapidamente un fumetto.

Una citazione correlata dal post del blog di Yossi Kreinin all'indirizzo http://www.yosefk.com/blog/i-want-a-struct-linker.html :

Hai una sorta di struttura di dati che passi molto in giro. Presto, la cosa più preziosa della struttura non sono i dati che conserva, ma il fatto che siano disponibili fino in fondo attraverso un flusso peloso di controllo.

Le variabili globali sono un modo classico per far "gridare" il codice a codice distante, ma sono noti per essere problematici. Le variabili con ambito dinamico sono un modo più limitato, ma sono anche problematiche.

Esistono ricerche sul linguaggio di programmazione volte a risolvere questo problema? Possiamo semplificare l'aggiunta di flussi di dati imprevisti a una base di codice di grandi dimensioni, pur mantenendo controlli statici, test di unità semplici e altri vantaggi?


Il modo in cui stai formulando la tua domanda immagino che tu abbia in mente un flusso di dati in un singolo processo, nessuna comunicazione tra processi. Quindi quale tipo di problema vedi che non può essere risolto dai meccanismi standard di mittente / ascoltatore di eventi?
Doc Brown,

Un esempio inventato: immagina che nel profondo del tuo sistema ci sia del codice che invia all'utente un messaggio di testo. E ottieni un nuovo requisito secondo cui il testo del messaggio dovrebbe dipendere dall'ora corrente nel fuso orario dell'utente. Il callstack si presenta così: un codice che conosce il fuso orario dell'utente, chiama un metodo che chiama un metodo che (... ripeti 15 volte) chiama un metodo che genera il testo del messaggio. Questo è un semplice esempio per i miei standard, perché implica la comunicazione solo verso il basso, ma è comunque necessario modificare le firme di 15 metodi per apportare la tua banale modifica.
Vladimir Slepnev,

Bene, suppongo che ciò che può aiutare sia modellare esplicitamente il flusso di dati e separare i componenti dal flusso di dati. L'ingegnere del software tedesco sta scrivendo molto su questo argomento, la maggior parte degli articoli in tedesco. Ecco un articolo di entrata in inglese di lui: geekswithblogs.net/theArchitectsNapkin/archive/2011/03/19/…
Doc Brown,

Penso che un'API interna singleton potrebbe aiutare. Sarebbe accessibile in tutta l'applicazione e incapsulerebbe tutta la logica di recupero dei dati.
superM,

Risposte:


1

Ti riferisci a CDI (Context Dependency Injection) AKA IoC (Inversion of Control). Java JSF e Spring Framework sono alcuni esempi. ASP.NET MVC ha plugin come Unity. Javascript sta iniziando ad avere strutture organizzate usando librerie come RequireJS, che ha un comportamento di iniezione visto in molti framework JS moderni. Questo è per il cablaggio di applicazioni locali e remote.

Per un accoppiamento lento tra le reti, le aziende preferiscono utilizzare i servizi Web con SOAP, REST, AJAX o chiamate remote con metodo RPC. In Java è possibile utilizzare JAX-WS o .NET WCF per creare servizi distribuiti. Quindi li allinea in un bus di servizio o "flusso di dati" da qualsiasi lingua o piattaforma come client. Ruby, Python, Scala, Java, C #, ... qualsiasi cosa.

L'accoppiamento allentato consente di dividere e superare i problemi e i servizi sono spesso il punto di accesso a un database per l'estrazione dei dati. Salendo la scala abbiamo la bestia chiamata Message Queue. Quella strada conduce a quadri di tipo aziendale e infrastrutturale.

Se il tuo progetto insiste su nessuna rete, tuttavia, ci sono lingue come Scala, Akka, NodeJS ecc. Che sono progettate per un elevato flusso di dati all'interno di una singola applicazione. Funzionano anche con alcune o tutte le tecnologie precedentemente menzionate per progetti complessi. Ad esempio, Scala può essere utilizzato con i servizi REST JAX-RS per estrarre una sorta di "dati globali" da un'origine dati e disporre di Spring per il cablaggio interno IoC. Esistono anche molti framework di esecuzione aziendale o di flusso di lavoro in strumenti JBoss, .NET e GUI come MuleESB. In fase di sviluppo, Eclipse e Netbeans consentono di trascinare e rilasciare i servizi in una schermata del diagramma di flusso visivo.

Infine, Java ha ancora i fagioli Singleton. Per regolare i metodi in fase di esecuzione, utilizzare i proxy o i framework di riflessione. Ma onestamente, è così 1999.

Se stai effettuando molte chiamate per inviare a un utente un messaggio in base al fuso orario, a mio avviso, probabilmente c'è un modo in 2 passaggi per ottenere lo stesso effetto che l'utente vede. Ma sì, i framework CDI sono indossati dalle lingue esistenti come un cappotto che offre loro tutti i poteri flessibili che hai citato. Mi piace definirlo il subconscio del mio programma, occupandomi senza problemi di lavoro sporco.


Le code dei messaggi possono essere eccessive, ma la messaggistica è il modo perfetto per attivare gli eventi su tutta la linea. Java utilizza Message Driven Beans (MDB) e ciò dovrebbe consentire al programma di inviare o ricevere "conversazioni" tra loro. Puoi farlo in questo modo per il bonus asincrono.
Senor Developer

Grazie per i suggerimenti! Sicuramente mi chiedo come potrebbe essere un linguaggio se fosse progettato da zero per supportare l'iniezione di dipendenza e schemi simili.
Vladimir Slepnev il

0

Il modo più semplice per farlo su larga scala è in realtà utilizzare una sorta di API di incapsulamento dei dati. Potrebbe trattarsi di un negozio NoSQL o potrebbe essere un RDBMS incapsulato (o potrebbe infatti trovarsi sia in tempi e luoghi diversi nella stessa applicazione - non c'è motivo per cui non si possa avere un RDBMS a lungo termine archiviazione e un db NoSQL che gestisce il controllo dello stato a breve termine). Potrebbe anche essere una serie di oggetti singleton.

Le strutture dei dati possono quindi essere rese disponibili in una sorta di spazio neutro, in modo un po 'gestito. Questo è l'approccio che adottiamo con LedgerSMB (ma con alcune variabili semi-globali per quelli che sono essenzialmente singoli nascosti, ma di nuovo questi sono gestiti, abbiamo scelto di nascondere direttamente l'oggetto perché ha reso un po 'più semplice la gestione delle variabili ma poi ci sono tutti e 4).

Naturalmente ogni approccio ha dei compromessi e non è possibile aggirare tali compromessi. La chiave è esaminare quali sono i compromessi (gestione vs prestazioni vs pulizia del codice rispetto a potenziali insidie ​​di codifica) e prendere una decisione in base a ciò che è meglio per la tua applicazione.


Grazie per la risposta! Mi sembra che la ricerca sul linguaggio di programmazione possa aiutare a risolvere questo problema. Ad esempio, se il codice legge alcuni dati da un database globale o da singoli separati, potrebbe esserci una garanzia statica / dichiarativa sui dati richiesti.
Vladimir Slepnev,

-1

Se usi (o citi) le parole

hairy flow of control

quindi presumo che il tuo codice sia davvero un casino. Dovresti lasciarlo cadere immediatamente. Se usi la modularizzazione / separazione delle preoccupazioni, non esiste un "flusso peloso di controllo". Il tuo codice manca semplicemente di semplicità, che è anche inferibile dal fatto che hai fatto riferimento a variabili globali :-).


Perché il downvote? Alla citazione mancava l'introduzione che supporta esattamente il mio punto di vista: "(è probabilmente classificato come" Antipattern "o" Odore di codice "e come tale ha un nome nelle cerchie appropriate, ma non lo saprei, quindi lascia senza nome) "
user127749

2
Questa non è davvero una risposta alla domanda, questa è probabilmente la ragione del downvote
Daniel Gratzer

Vorrei quindi riformulare la domanda: esiste qualche trucco magico per annullare il disordine del codice che viola uno dei principi di base della progettazione del software: KISS (mantienilo semplice, stupido)? Il trucco non è magico, o è un programmatore che non può essere sostituito perché conosce tutti i dettagli non così ovvi (che uccideranno l'azienda a lungo termine), o per ristrutturare la base di codice. Sfortunatamente, molte aziende inizialmente non si preoccupano della corretta progettazione del codice o non ne comprendono nemmeno le conseguenze, quindi devono riscrivere il loro codice almeno una volta, molte addirittura lo riscrivono più volte su ...
user127749
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.