Imbarazzantemente ho introdotto una libreria "comune", così chiamata, in un ambiente di squadra un paio di decenni fa. All'epoca non capivo davvero le dinamiche di ciò che sarebbe potuto accadere in una squadra scarsamente coordinata nel giro di pochi mesi.
Quando l'ho presentato, ho pensato di chiarire e documentare anche che è per cose che tutti concorderemmo che troviamo utile su base giornaliera, che è destinato ad essere una biblioteca minimalista e che la biblioteca non dovrebbe dipendere da nient'altro oltre al libreria standard in modo che sia il più semplice possibile da implementare in nuovi progetti. All'epoca pensavo che fosse la nostra piccola estensione alla libreria standard per cose che, nel nostro particolare dominio, abbiamo trovato utili su base giornaliera.
E è iniziato abbastanza bene. Abbiamo iniziato con una libreria matematica ( common/math*
) di routine che tutti usavamo quotidianamente, poiché lavoravamo in computer grafica che era spesso pesante sull'algebra lineare. E dal momento che spesso interagivamo con il codice C, abbiamo concordato alcune utili funzioni di utilità come quelle find_index
, a differenzastd::find
in C ++, restituirebbe un indice a un elemento trovato in una sequenza anziché in un iteratore che imitava il modo in cui funzionavano le nostre funzioni C - cose di questo tipo - un po 'eclettico ma minimalista e ampiamente usato abbastanza da rimanere familiare e pratico per tutti e la familiarità istantanea è un criterio estremamente importante per come la vedo nel tentativo di creare qualsiasi cosa che sia "comune" o "standard" poiché se è veramente "comune", dovrebbe avere quella qualità familiare su di esso a causa della sua ampia adozione e uso quotidiano.
Ma nel tempo le intenzioni di progettazione della biblioteca mi sono sfuggite di mano quando le persone hanno iniziato ad aggiungere cose che usavano personalmente che pensavano potessero essere utili a qualcun altro, solo per trovare nessun altro che lo usasse. E in seguito qualcuno ha iniziato ad aggiungere funzioni che dipendevano da OpenGL per le routine comuni relative a GL. Successivamente abbiamo adottato Qt e le persone hanno iniziato ad aggiungere codice che dipendeva da Qt, quindi già la libreria comune dipendeva da due librerie esterne. A un certo punto qualcuno ha aggiunto routine di shader comuni che dipendevano dalla nostra libreria di shader specifica per l'applicazione, e a quel punto non si poteva nemmeno distribuirlo in un nuovo progetto senza introdurre Qt, OGL e la nostra libreria di shader e la scrittura specifiche dell'applicazione uno script di compilazione non banale per il tuo progetto. Così si è trasformato in questo pasticcio eclettico e interdipendente.
Ma ho anche scoperto discutendo cosa dovrebbe e non dovrebbe andare in questa libreria che ciò che è considerato "comune" può facilmente trasformarsi in un'idea molto soggettiva se non si imposta una regola molto rigida che ciò che è "comune" è ciò che tutti tendono a trovare utile su base giornaliera. Qualsiasi allentamento degli standard e degrada rapidamente dalle cose che tutti trovano utili su base giornaliera a qualcosa che un singolo sviluppatore trova utile che potrebbe avere la possibilità di essere utile per qualcun altro, e a quel punto la libreria si degrada in un disordine eclettico molto velocemente .
Inoltre, quando raggiungi quel punto, alcuni sviluppatori possono iniziare ad aggiungere cose per il semplice motivo che non amano il linguaggio di programmazione. Potrebbe non piacere la sintassi di un ciclo for o una chiamata di funzione, a quel punto la libreria sta iniziando a riempirsi di cose che stanno solo combattendo la sintassi fondamentale del linguaggio, sostituendo un paio di righe di codice semplice che non è proprio duplicazione di qualsiasi logica fino a una singola riga concisa di codice esotico familiare solo allo sviluppatore che ha introdotto tale abbreviazione. Quindi uno sviluppatore del genere potrebbe iniziare ad aggiungere più funzionalità alla libreria comune implementata utilizzando tali shorthands, a quel punto sezioni significative della biblioteca comune si intrecciano con queste esotiche scorciatoie che potrebbero sembrare belle e intuitive per lo sviluppatore che le ha presentate ma brutte, estranee e difficili da capire per tutti gli altri. E a quel punto penso che tu sappia che ogni speranza di fare qualcosa di veramente "comune" è persa, dal momento che "comune" e "non familiare" sono idee polari opposte.
Quindi ci sono tutti i tipi di lattine di worm lì, almeno in un ambiente di squadra vagamente coordinato, con una biblioteca con ambizioni tanto ampie e generalizzate come solo "roba di uso comune". E mentre il problema di fondo potrebbe essere stato il coordinamento allentato sopra ogni altra cosa, almeno più librerie intese a servire uno scopo più singolare, come una libreria destinata a fornire routine matematiche e nient'altro, probabilmente non si degraderebbero in modo significativo in termini di progettare la purezza e le dipendenze come una biblioteca "comune". Quindi, a posteriori, penso che sarebbe molto meglio sbagliare dal lato delle biblioteche che hanno intenzioni di progettazione molto più chiare. Ho anche scoperto nel corso degli anni che restringere lo scopo e restringere l'applicabilità sono idee radicalmente diverse.
Inoltre, devo ammettere che almeno un po 'poco pratico e la cura forse un po' troppo dell'estetica, ma il modo in cui tendo a percepire la mia idea della qualità di una biblioteca (e forse anche la "bellezza") è giudicato più dal suo legame più debole che è più forte, in un modo simile che se mi hai presentato il cibo più appetitoso del mondo ma, sullo stesso piatto, metti lì qualcosa che marcisce e che ha un cattivo odore, tendo a voler rifiutare l'intero piatto. E se sei come me al riguardo e fai qualcosa che invita ogni sorta di aggiunta come qualcosa chiamato "comune", potresti ritrovarti a guardare quella piastra analogica con qualcosa che marcisce sul lato. Allo stesso modo, penso che sia buono se una biblioteca è organizzata, denominata e documentata in modo tale da non farlo t invitano sempre più aggiunte nel tempo. E ciò può valere anche per le tue creazioni personali, dal momento che ho sicuramente creato alcune cose marce qua e là, e "si guasta" molto meno se non viene aggiunto al piatto più grande. Separare le cose in librerie piccole e molto singolari ha anche la tendenza a disaccoppiare meglio il codice, anche se solo per la pura virtù che diventa molto meno conveniente iniziare ad accoppiare tutto.
La deduplicazione del codice è stata martellata in me nel corso degli anni ma mi sento come se dovessi provarla questa volta.
Quello che potrei suggerire nel tuo caso è iniziare a semplificare la deduplicazione del codice. Non sto dicendo di copiare e incollare grossi frammenti di codice mal testato, soggetto a errori o qualcosa del genere, o duplicare enormi quantità di codice non banale che ha una discreta probabilità di richiedere cambiamenti in futuro.
Ma soprattutto se sei della mentalità per creare una libreria "comune", per la quale presumo che il tuo desiderio sia quello di creare qualcosa di ampiamente applicabile, altamente riutilizzabile e forse idealmente qualcosa che trovi utile oggi come fai tra un decennio da oggi , quindi a volte potresti persino aver bisogno o desiderare una duplicazione per ottenere questa qualità sfuggente. Perché la duplicazione potrebbe effettivamente fungere da meccanismo di disaccoppiamento. È come se desideri separare un lettore video da un lettore MP3, quindi devi almeno duplicare alcune cose come batterie e dischi rigidi. Non possono condividere queste cose o sono indivisibilmente accoppiati e non possono essere usati indipendentemente l'uno dall'altro, e a quel punto le persone potrebbero non essere più interessate al dispositivo se tutto ciò che vogliono fare è riprodurre MP3. Ma qualche tempo dopo aver diviso questi due dispositivi, potresti scoprire che il lettore MP3 può beneficiare di un design della batteria diverso o di un disco rigido più piccolo rispetto al lettore video, a quel punto non stai più duplicando nulla; ciò che inizialmente era iniziato come duplicazione per consentire a questo dispositivo interdipendente di dividersi in due dispositivi separati e indipendenti, in seguito si sarebbe potuto produrre progetti e implementazioni che non sono più ridondanti.
Vale la pena considerare le cose dal punto di vista di quello che usa una biblioteca. Vorresti davvero usareuna libreria che minimizza la duplicazione del codice? È probabile che non lo farai perché uno che lo farà dipenderà naturalmente da altre librerie. E quelle altre librerie potrebbero dipendere da altre librerie per evitare di duplicare il loro codice, e così via, fino a quando potresti aver bisogno di importare / collegare 50 librerie diverse solo per ottenere alcune funzionalità di base come caricare e riprodurre un file audio, e questo diventa molto ingombrante . Nel frattempo, se una simile libreria audio ha deliberatamente scelto di duplicare alcune cose qua e là per raggiungere la sua indipendenza, diventa molto più facile da usare in nuovi progetti e le probabilità sono che non debba essere aggiornato quasi altrettanto spesso da quando ha vinto ' Deve cambiare a seguito di una modifica delle sue librerie esterne dipendenti, che potrebbe tentare di soddisfare uno scopo molto più generalizzato di quello di cui la libreria audio ha bisogno.
Quindi a volte vale la pena scegliere deliberatamente di duplicare un po '(consapevolmente, mai per pigrizia - in realtà per diligenza) al fine di disaccoppiare una libreria e renderla indipendente perché, attraverso tale indipendenza, raggiunge una gamma più ampia di applicabilità pratica e stabilità uniforme (niente più accoppiamenti afferenti). Se vuoi progettare le librerie più riutilizzabili possibili che ti dureranno da un progetto al successivo e nel corso degli anni, oltre a restringere al minimo il suo ambito, suggerirei davvero di considerare di duplicare un po 'qui. E naturalmente scrivi test unitari e assicurati che sia veramente accuratamente testato e affidabile in quello che sta facendo. Questo è solo per le biblioteche che vuoi davvero impiegare del tempo per generalizzare a un punto che va ben oltre un singolo progetto.