È davvero possibile che le librerie non dipendano da altre librerie?

3

Spesso vedo il consiglio che dovresti provare a rendere indipendente ogni libreria. Eppure in realtà non riesco mai a ottenerlo. Questo consiglio di BS o è effettivamente possibile in qualche modo realistico?

Esempio: scrivo una libreria vettoriale 2D, quindi la uso per creare una libreria di collisioni 2D. Quindi creo una libreria di fisica 2D che utilizza sia la libreria vettoriale 2D che la libreria Collision 2D. Mi sono seriamente aspettato di trovare un modo per rendere la libreria fisica non dipendente dalle altre 2 librerie? Probabilmente alla fine vorrò essere in grado di serializzare / deserializzare la fisica e i dati di collisione, il che significa che vorrò farli ulteriormente dipendere da qualche libreria di serializzazione.

Un altro esempio: ho una libreria di stringhe con molte funzioni di stringa (penso endsWith(str, ending) e startsWith(str, start) o qualsiasi altra cosa. Poi scrivo una libreria di template che usa la mia libreria di stringhe.

Raramente riesco a scrivere una nuova libreria che non usa altre librerie.

Potrei scrivere interfacce e poi scrivere adattatori per tutti quelli che tentano di disaccoppiare una libreria da un'altra, ma è improbabile che sia performante e spesso i modelli delle diverse librerie significano che anche se potessi disaccoppiare con un'interfaccia cercando di usare una libreria diversa da quella originariamente disaccoppiata finirà per essere impossibile o massicciamente non performante.

Quindi, questo consiglio originale è BS o esiste un modo per applicare effettivamente il consiglio nel mondo reale?

    
posta gman 05.04.2014 - 00:37
fonte

4 risposte

13

L'idea alla base di questo consiglio è che la gestione delle dipendenze fa schifo su molte piattaforme (parola chiave: " inferno DLL ", sebbene il problema esista in vari gradi per tutte le piattaforme e tutte le lingue). Questo non è solo un problema di avere librerie compatibili per il collegamento dinamico, ma anche per scaricare la versione corretta di ogni dipendenza prima della compilazione. Se queste dipendenze non vengono gestite automaticamente, ciò può andare storto.

Una volta implementata una corretta gestione delle dipendenze (ad esempio tutte le principali distribuzioni Linux hanno gestori di pacchetti come apt o rpm, esistono varie soluzioni specifiche per la lingua come tlmgr, cpan, pip, gem, npm, maven, ... 1 il costo di avere dipendenze è trascurabile quando si distribuisce la libreria.

E tu dovresti riutilizzare il codice esistente, laddove possibile: è generalmente impossibile riscrivere tutto da solo, e possiamo guardare molto più lontano "in piedi sulle spalle dei giganti" (Newton ). L'astrazione è un prerequisito per la creazione di programmi non banali.

Incorporare le dipendenze direttamente nella libreria (ad esempio riscrivere queste dipendenze) può essere un'opzione valida in alcuni casi:

  • Questo caso di Non-inventato-Qui è giustificato, ad es. per motivi legali.
  • I livelli di prestazioni richiesti possono essere raggiunti solo con codice finemente sintonizzato.
  • Non esiste alcuna infrastruttura per la distribuzione, quindi tutto deve essere raggruppato insieme.

1: tlmgr (TeX), cpan (Perl), pip (python), gem (Ruby), npm (nodo), maven (java)

    
risposta data 05.04.2014 - 01:21
fonte
9

È interamente possibile costruire librerie usando il codice nudo. In effetti, esco su un arto e dico che non è raro farlo. Tuttavia ...

La storia del software sta ponendo astrazioni in cima alle astrazioni più vecchie. Una volta capito come fare una cosa, è consuetudine avvolgere quella cosa in una funzione, modulo o libreria e chiamarla, piuttosto che reinventare la ruota ogni volta.

In questo modo, ti trovi sulle spalle di quelli che sono venuti prima di te. Quindi puoi scalare l'Everest a piedi o salire in elicottero in vetta alla cima. Ogni approccio ha i suoi vantaggi.

    
risposta data 05.04.2014 - 01:05
fonte
2

Direi che le librerie dovrebbero dipendere solo dalle librerie di cui ha assolutamente bisogno per portare a termine il lavoro. Non dovrebbero avere bisogno di dipendere da librerie che dipendono da parti indipendenti del sistema.

A volte vedrai che LibraryA dipende da LibraryB e LibraryC. Quindi se LibraryZ deve dipendere da LibraryA, allora deve anche dipendere da LibraryB e C. Questo è il tipo di inferenza di dipendenza che dovrebbe essere evitata quando possibile. LibraryZ non dovrebbe aver bisogno di sapere nulla sulle Librerie B & C.

Un esempio del mondo reale leggermente arrotondato ....

Attualmente sto costruendo un sistema con un numero di librerie di plugin e ho dovuto rispondere a una domanda simile ma leggermente diversa:

"È possibile avere plugin che non conoscono altri plug-in, ma utilizzano comunque informazioni / funzionalità da altre librerie di plugin?"

(ad esempio, le Pagine Web hanno la Navigazione su di esse, ma per costruire un widget di Navigazione - devi sapere quali Pagine sono disponibili e gli URL di quelle pagine)

Dopo molte indagini e prototipi ho deciso di installare un sistema di bus di messaggistica. Tutto conosce i messaggi per il sistema (e alcune altre librerie di implementazione di base), ma non sanno nulla su cosa gestisce tali messaggi.

Anche se questo non è esattamente "le librerie non dipendono da altre librerie" in questa domanda, limita seriamente l'estensione di dipendenza injection e dll hell, dato che PluginLibraryZ non sa assolutamente nulla di PluginLibraryA o di nessuna delle librerie che PluginLibraryA dipende da (ad es. Libreria B & C dall'alto). Le librerie dei plugin conoscono solo la libreria dei messaggi e altre librerie che sono assolutamente necessarie per svolgere il proprio lavoro e nient'altro.

Quindi, per il tuo esempio qui, la tua libreria fisica dipenderebbe ancora dalle librerie 2D vettoriali e Collision 2D - ma un'altra parte del sistema (ad es. la libreria ThrowBall) che aveva bisogno di usare la libreria fisica poteva semplicemente sollevare un messaggio di "WhereDoesBallLand" con tutti i parametri richiesti (ad es. Peso della palla, angolo e forza di lancio ecc.). Quindi la tua biblioteca di Fisica farebbe tutti i calcoli per scoprire dove la pallina sarebbe atterrato, e la biblioteca ThrowBall avrebbe ottenuto una risposta alla domanda "Dove finisce la palla". Ma la libreria ThrowBall non dipenderebbe dalla libreria Physics o dal "D vector o libagati Collision.

NOTA: sono sicuro che i Message Bus non sono l'unico modo per ottenere questa separazione di funzionalità e dipendenze, ma ha funzionato nel mio problema di dipendenza dalla libreria di plugin. L'ho persino scaricato sul sito Web di frontend, non avevo bisogno di sapere nulla delle librerie di plugin - solo i messaggi e un paio di librerie di funzionalità di base.

    
risposta data 05.04.2014 - 20:03
fonte
1

I often see the advice that you should try to make each library independent. And yet in reality I can never seem to achieve this.

Questo tipo di consiglio, come la maggior parte delle cose, dovrebbe essere preso con moderazione accompagnato da una grande dose di pensiero critico sulla tua situazione specifica.

40 o 50 anni fa, i computer non venivano utilizzati per lavori in qualsiasi luogo vicino al livello di sofisticazione che sono oggi. La relativa semplicità dei problemi di quell'epoca significava che i blocchi costitutivi richiesti erano di per sé molto più semplici, quindi qualsiasi libreria casuale aveva più probabilità di avere poche o nessuna dipendenza. La nostra capacità di affrontare compiti più complessi deriva da ciò che abbiamo imparato conquistando quelli più facili. Ne consegue che, avendo risolto un problema e implementato il codice per farlo, non risolviamo il problema successivo rivisitando tutto ciò che abbiamo fatto come se fosse tutto nuovo materiale. Non faremmo mai progressi in questo modo.

Oltre ai casi patologicamente semplici come una biblioteca matematica a virgola mobile in cui le funzioni sono abbastanza semplici da non richiedere dipendenze, molti casi reali li hanno e non c'è peccato. Essere in grado di rompere le tue librerie nelle parti giuste dimostra che hai una buona padronanza sul riutilizzo e che capisci dove posizionare i confini.

Se stai entrando in interfacce e adattatori o in una libreria del lavello da cucina solo per rispettare la dogmatica di qualcuno definizione di "best practice", è probabilmente il momento di smettere e rivalutare ciò che stai facendo.

    
risposta data 05.02.2018 - 05:44
fonte