Pericoli di un'enorme applicazione monolitica

20

Il grande progetto su cui sto lavorando da un paio d'anni è un'applicazione di controllo (e di tutto) di un dispositivo avanzato, cuore del suo firmware.

Il dispositivo è abbastanza avanzato, con funzionalità più diverse di quelle che potrei dire dalla memoria, e il 98% di esse sono gestite da questo enorme eseguibile. In una mano, il programma è abbastanza gestibile, ben strutturato all'interno, adeguatamente documentato, c'è una ragionevole separazione di funzionalità da directory e file e così via.

Ma alla fine viene tutto raggruppato in un'unica applicazione che fa tutto, dalla comunicazione remota del database, alla gestione del touchscreen, alla gestione di una dozzina di vari protocolli di comunicazione, misurazioni, diversi algoritmi di controllo, acquisizione video, ora dell'alba e data della pasqua (seriamente, e sono necessari per scopi molto seri!) ... In generale, cose che sono molto sottilmente correlate, spesso legate solo attraverso alcuni dati che scorre tra alcuni moduli lontani.

Potrebbe essere fatto come diversi eseguibili separati che comunicano tra loro, ad esempio su socket, con uno scopo più specifico, magari caricati / scaricati secondo necessità e così via. Nessun motivo specifico per cui è stato creato in questo modo.

In una mano, funziona, e funziona bene. Il progetto è più semplice, senza mantenere la compilazione di più file binari. Anche la struttura interna è più semplice, quando puoi semplicemente chiamare un metodo o leggere una variabile invece di parlare su socket o memoria condivisa.

Ma d'altra parte, le dimensioni, la scala di questa cosa mi fanno strisciare fuori, mi sembra di pilotare Titanic. Mi è sempre stato insegnato a modulare, e raggruppare tutto in un file gigantesco mi sembra sbagliato. Un problema che conosco è un crash grave di un (anche insignificante) crash di tutti i moduli - ma la qualità del codice assicura che ciò non avvenga realmente nelle versioni di rilascio. In caso contrario, la separazione interna e la programmazione difensiva assicurano che questo funzionerà ancora correttamente anche se per qualche motivo metà dei moduli interni non funziona correttamente.

Quali altri pericoli ho trascurato? Perché questo mi insinua? È solo una paura irrazionale di sconosciuto? Sta facendo grandi progetti seri in questo modo una pratica accettata? O calma le mie paure o dammi una buona ragione per refactoring versione 2.0 in più file binari più piccoli.

    
posta SF. 13.07.2011 - 16:41
fonte

8 risposte

5

Ad eccezione del piccolo commento alla fine (secondo, supervisione della CPU) potresti descrivere la mia azienda. Sì, abbiamo bisogno anche di Pasqua.

Bene, siamo un po 'più avanti. Abbiamo diviso il grosso eseguibile e provato a utilizzare componenti standard per bit standard. Non è esattamente il grande miglioramento che speravi. In effetti, le prestazioni stanno diventando un grave problema anche con hardware più muscoloso. E i costi di manutenzione non sono diminuiti, ora che ci sono tonnellate di codice per serializzare e sincronizzare i dati su interfacce strette.

La lezione che ho imparato? Avere un singolo eseguibile è una soluzione ben collaudata per sistemi di piccole dimensioni, e abbiamo decenni di esperienza nella sua gestione. Tutti i nostri strumenti supportano questo in modo nativo. La modularità può essere eseguita anche all'interno di un singolo file eseguibile e quando è necessario scendere a compromessi sulla modularità per altri motivi, l'hacking rimane piccolo.

    
risposta data 14.07.2011 - 14:37
fonte
23

The device is quite advanced, with more different functionalities than I could say from memory, and 98% of them are handled by this one huge executable. In one hand, the program is quite maintainable, well modularized inside, properly documented, there's a reasonable separation of functionalities by directories and files and so on.

L'hai detto tu stesso - è abbastanza gestibile, ben modulare ...

Secondo me, e la maggior parte della gestione sarà d'accordo con me su questo, le modifiche non dovrebbero mai essere fatte per il gusto di cambiamenti. Non c'è niente di sbagliato in questo programma (la tua descrizione) a parte il fatto che non segue le ultime tendenze di programmazione (che sono menzionate in altre risposte).

Sì, è un programma più grande ... molti prima lo sono stati anche. È anche ben documentato, quindi tutto ciò che devi fare è studiare la sua organizzazione interna e vedrai la logica in esso. Dubito che tutti quelli che prima di te che lo hanno scritto fossero incompetenti. Quindi, esploralo un po ', imparalo ... dopodiché, mantienilo com'è fino a quando non apparirà un motivo valido per riscriverlo. Il tuo manager ti sarà grato per avere un buon rapporto costo / efficacia.

What other dangers did I overlook? Why does this creep me out? Is this just irrational fear of unknown? Is making serious big projects this way an accepted practice? Either calm my fears or give me a good reason to refactor version 2.0 into multiple smaller binaries.

Ti insinua perché è grande - ma poi di nuovo, nessuno si aspetta che tu lo impari tutto a memoria in una settimana. Quindi lavora, pezzo dopo pezzo, un po 'alla volta, fino a quando non ne prendi il controllo. Alla fine, imparerai che probabilmente è ben organizzato così com'è e come è organizzato.

Se dovessi riscriverlo, avresti ottenuto lo stesso risultato, ma allo stesso tempo lo hai rovinato per tutti quelli che erano abituati alla precedente organizzazione del codice. In questo modo, devi solo "adattarti".

    
risposta data 13.07.2011 - 17:26
fonte
16

Mi sentirei meglio se dicessi di avere tutto avvolto nei test unitari. Se non lo fai, dovresti creare una suite di test prima ancora di pensare a rearchitecting l'applicazione.

Avere una suite di test migliorerà la tua comprensione dell'applicazione e ti dirà quando un cambiamento nell'applicazione rompe qualcosa.

    
risposta data 13.07.2011 - 16:46
fonte
8

Se il codice è ben modulare con un basso accoppiamento e un'elevata coesione, è partizionato in modo efficace. Il sovraccarico di comunicazione dovrebbe essere inferiore all'interno di un unico processo rispetto a più processi.

Per i sistemi incorporati, il tuo unico processo potrebbe eliminare la necessità di implementare un O / S per eseguire tutti i processi che dovresti creare. Dovresti anche implementare un sistema per verificare che tutti i processi siano in esecuzione e riavviarli se possibile. Se non fosse possibile, dovresti reagire di conseguenza.

La suddivisione del codice in eseguibili separati aumenterebbe anche la dimensione complessiva del codice sorgente in quanto sarebbe necessario implementare tutto il codice client / server tra i moduli. Avresti anche bisogno di più casi di test per gestire questo codice e casi in cui il processo del server non era presente. I grandi progetti sono grandi, eliminando le complessità inutili, come sembra essere stato fatto qui, per tenerli più piccoli possibile.

I test sono una sorta di falsa pista qui, poiché i problemi saranno ancora lì con o senza test. I buoni test con entrambe le scelte di progettazione dovrebbero certamente essere incoraggiati. Mi aspetto che il test sia più semplice con il codice monolitico.

Forzare un arresto anomalo quando necessario è anche più facile con un eseguibile monolitico.

    
risposta data 13.07.2011 - 18:48
fonte
1

Se dovessi lavorare su un'applicazione monolitica così grande, le cose che mi farebbero impazzire sono la mancanza di incapsulamento, bassa coesione, alto accoppiamento e come testare tutto questo. I grandi monoliti sono spesso un invito ad abbandonare l'architettura appropriata e iniziare la discesa in una grande palla di fango .

Una volta che ciò accade, i test diventano un incubo e tu sei sulla strada dell'obsolescenza.

Tuttavia, se il codice è ben strutturato e ben mantenuto, e i principi di alta coesione, accoppiamento basso e incapsulamento adeguato sono rispettati, non vedo motivi per ricondizionarlo in unità più piccole.

Tuttavia, è necessario avere dei test validi.

    
risposta data 13.07.2011 - 17:10
fonte
1

Idealmente, la risposta è sì. Avere più file binari ha il potenziale per renderlo più stabile ....

... tuttavia, hai anche detto che il codice all'interno della base di codice monolitica è ben scritto e modularizzato, il che significa che non hai a che fare con un enorme pasticcio ingarbugliato, solo un'enorme base di codice ...

Nel complesso, direi che il detto applicabile è: "Non lasciare che il perfetto sia il nemico del bene". Mentre sento che hai ragione nel dire che una base di codice monolitica è cattiva, sento anche che non vale la pena di preoccuparsene.

Sarebbe ragionevole andare avanti inserendo nuove porzioni di codice nei propri binari, ma tornare indietro e rifattorizzare probabilmente non vale la pena.

    
risposta data 13.07.2011 - 17:11
fonte
1

Se stai usando un singolo processo, c'è una possibilità che un puntatore jolly da uno dei tuoi sottomoduli corrompa un pezzo di memoria critico (e blocchi l'intera cosa).

Se stai utilizzando processi diversi, almeno non stai usando lo stesso heap o stack di chiamate, e potrebbe anche essere più semplice riavviare un singolo sottoprocesso.

The internal structure is easier too, when you can just call a method or read a variable instead of talking over sockets or shared memory.

Ridurre tutto in più processi ti costringerà anche a ripulire il design ed evitare che ogni modulo inizi a utilizzare metodi interni di altri moduli.

Ciò detto è probabilmente un compito scoraggiante.

Quello che potresti iniziare a fare, è decidere che ogni nuovo modulo dovrebbe essere un processo isolato.

    
risposta data 13.07.2011 - 17:10
fonte
0

Quando entro nel regno in cui il progetto è troppo grande per ingolfarlo tutto in una volta, costruisco un grafico da appendere al muro che espone tutte le sezioni più grandi e come si adattano. Poi, quando lavoro, posso fare riferimento al modulo su cui mi sto concentrando e avere un promemoria visivo di come si integri nel tutto.

È piuttosto probabile che le complessità e i pericoli legati al mantenimento di un sistema di generazione e controllo delle versioni per più binari disconnessi supereranno di gran lunga il tuo disagio con un progetto così ampio e monolitico.

    
risposta data 13.07.2011 - 21:39
fonte

Leggi altre domande sui tag