Best practice per la condivisione di piccoli frammenti di codice tra i progetti

102

Cerco sempre di seguire rigorosamente il principio DRY ; ogni volta che ho ripetuto il codice per pigrizia, morde più tardi quando ho bisogno di mantenere quel codice in due punti.

Ma spesso scrivo piccoli metodi (forse 10-15 linee di codice) che devono essere riutilizzati in due progetti che non possono fare riferimento l'un l'altro. Il metodo potrebbe essere qualcosa a che fare con networking / strings / MVVM ecc. Ed è un metodo generalmente utile non specifico per il progetto in cui si trova originariamente.

Il modo standard per riutilizzare questo codice sarebbe creare un progetto indipendente per il codice riutilizzabile e fare riferimento a quel progetto quando ne hai bisogno. Il problema è che finiamo in uno dei due scenari tutt'altro che ideali:

  1. Finiamo con decine / centinaia di piccoli progetti - ognuno per ospitare le piccole classi / metodi che dovevamo riutilizzare. Vale la pena creare un .DLL completamente nuovo solo per un piccolo pezzetto di codice?
  2. Finiamo con un singolo progetto che contiene una crescente collezione di metodi e classi non correlate. Questo approccio è ciò che una società per cui ho lavorato per fare; avevano un progetto chiamato base.common che aveva cartelle per cose come ho detto sopra: networking, manipolazione delle stringhe, MVVM ecc. Era incredibilmente maneggevole, ma riferendola inutilmente trascinava con sé tutto il codice irrilevante di cui non avevi bisogno.

Quindi la mia domanda è:

In che modo il team di un software riesce a riutilizzare piccoli bit di codice tra i progetti?

Sono particolarmente interessato se qualcuno ha lavorato in un'azienda che ha politiche in questo settore, o che ha incontrato personalmente questo dilemma come me.

nota: Il mio uso delle parole "Progetto", "Soluzione" e "Riferimento" provengono da uno sfondo nello sviluppo .NET in Visual Studio. Ma sono sicuro che questo problema è indipendente dalla lingua e dalla piattaforma.

    
posta George Powell 30.03.2013 - 14:40
fonte

12 risposte

75

Se sono davvero metodi / classi riutilizzabili, potresti scriverli in un piccolo numero di librerie "Swiss Army Knife". Lo facciamo abbastanza spesso nella mia azienda; li chiamiamo librerie di framework:

  • Framework.Data - Utilità per lavorare con le query del database.
  • Framework.ESB - Metodi standard per l'interazione con il nostro bus di servizio aziendale
  • Framework.Logging - Sistema di registrazione unificato
  • Framework.Services - Utilità per interagire con i servizi web
  • Framework.Strings - Utilità per la manipolazione avanzata di stringhe / ricerca stringa fuzzy ecc.
  • ...

In tutto, ci sono circa una dozzina di librerie. Puoi davvero distribuire il codice come meglio credi, quindi non devi finire con centinaia o buttare tutto in un unico gigantesco assemblaggio. Trovo che questo approccio si adatti perché solo alcuni dei nostri progetti avranno bisogno di Framework.Data e solo pochi avranno mai bisogno di Framework.Strings , in modo che i consumatori possano selezionare solo le parti del framework che sono rilevanti per il loro particolare progetto.

Se sono davvero solo frammenti e non metodi / classi reali che possono essere facilmente riutilizzati, potresti provare a distribuirli come frammenti di codice nell'IDE (ad esempio Frammenti di codice di Visual Studio ). I team con cui ho lavorato in passato avevano una libreria di frammenti di codice comune che rendeva più facile per tutti seguire le nostre pratiche di codifica standard anche con il codice interno.

    
risposta data 30.03.2013 - 15:40
fonte
21

Non sono d'accordo con la risposta accettata per molte ragioni.

Nella mia esperienza, quando vedo le librerie "varie" come la risposta accettata, sono una scusa per reinventare la ruota (o non inventato qui (NIH) ) - un peccato molto più grande della violazione di Dont Repeat Yourself (DRY) .

A volte violando DRY può essere un ragionevole compromesso, è meglio che introdurre un accoppiamento stretto. Riutilizzare è una preoccupazione secondaria rispetto al buon design orientato agli oggetti. Un po '(intendo una piccola quantità, applica la Regola dei tre ) della duplicazione è più facile da capire di codice base spaghetti.

L'approccio di numerose librerie di scopi generali non è un buon esempio. Porta a una granularità fine dell'assemblaggio e troppi assembly sono cattivi. Recentemente ho ridotto un interno da 24 librerie a 6 librerie. Ha migliorato il tempo di compilazione da diversi minuti a ~ 20 secondi. Visual Studio è anche più lento da caricare e meno reattivo con più assiemi. Avere troppe librerie porta anche a confusione su dove il codice dovrebbe vivere; preferisco regole più semplici e semplici.

Perché le cose nel .Net Framework non sono abbastanza buone? Il quadro è abbastanza grande; molte volte ho visto codice che re-implementa cose che già esistono lì. Assicurati davvero che i tuoi framework stiano colmando le lacune nel framework .Net e non esista solo per ragioni estetiche (ad esempio "Non mi piace il framework .Net qui" o forse alcuni ottimizzazione prematura )

L'introduzione di un altro livello nella tua architettura ha un costo di complessità significativo. Perché lo strato esiste? Ho visto un falso riutilizzo, con ciò intendo dire che il codice è costruito su un framework interno. Sarebbe stato molto più efficiente implementarlo direttamente sulle librerie standard.

L'utilizzo di tecnologie standardizzate (come il framework .Net e le popolari librerie di terze parti / open source) presenta vantaggi che spesso superano i vantaggi tecnologici comparativi derivanti dalla creazione autonoma. È più facile trovare talenti che conoscano queste tecnologie e i tuoi sviluppatori esistenti investiranno di più nell'apprenderlo.

I miei consigli:

  • Non condividere questo codice.
  • Crea una nuova libreria se ha uno scopo coesivo non utilizzare il schema di progettazione della palla di fango .
  • Riutilizza le librerie di terze parti esistenti laddove possibile.
  • Preferisci un minor numero di assiemi, con regole più semplici su dove dovrebbe essere il codice.
risposta data 23.06.2013 - 19:34
fonte
11

Per piccoli bit di codice - diciamo una singola classe senza dipendenze - tendiamo a copiare e incollare il codice nei progetti. Sembra una violazione di DRY, e ammetto che può essere a volte. Ma a lungo termine è stato molto meglio che avere una sorta di progetto di comuni commessi con più teste per diversi motivi.

In primo luogo, è più semplice avere a portata di mano il codice, specialmente quando si creano e si debuggano.

In secondo luogo, invariabilmente vorrete fare qualche piccola modifica al codice comune per quel progetto. Se hai una copia locale della fonte di quanto tu possa solo fare il tweak e chiamarlo un giorno. Se è presente una libreria condivisa, è possibile che tu stia prendendo in considerazione la libreria e quindi assicurati di non interrompere tutte le altre app o creare un incubo di versioni.

Quindi, se non è abbastanza robusto per il proprio spazio dei nomi, tendiamo a inserirli nei bit appropriati del progetto e a chiamarli un giorno.

    
risposta data 01.04.2013 - 23:30
fonte
6

La seconda soluzione che descrivi non è poi così male. In .NET si fa riferimento anche a un assembly dal GAC anche se si utilizza solo una singola classe di esso. "Trascinare il codice irrilevante" non è un problema come potresti pensare. In questo caso è fondamentale almeno mantenere metodi e classi correlati organizzati in diversi spazi dei nomi. Inoltre, devono essere applicate buone pratiche per la progettazione dell'API per evitare che questa soluzione diventi un disastro.

Se si tratta di bit di codice molto piccoli, penso che il seguente approccio sia un buon complemento a un progetto comune: consentirgli di essere duplicati in diverse soluzioni. Affrontali come le migliori pratiche: documentale e comunicale al team.

    
risposta data 30.03.2013 - 15:35
fonte
6

Ho sempre lavorato solo in ambienti "enterprise" in cui questo genere di cose è stato un problema e ogni volta che è stata adottata la seconda opzione. Per la maggior parte, ha funzionato bene perché non c'è stato alcun vincolo sull'impronta dell'applicazione.

Tuttavia, dopo aver trascorso l'ultima settimana con una start-up che sta eseguendo il proprio server Nuget, sono propenso a suggerire questa alternativa come valida. Naturalmente i problemi che mi aspetto di emergere saranno intorno alla scoperta-abilità.

Se i progetti sono opportunamente granulari e gli spazi dei nomi sono ragionevoli, allora posso vedere che questo sta diventando un approccio popolare nei luoghi.

    
risposta data 30.03.2013 - 16:07
fonte
6

Di recente ho pensato a questo e quello che mi è successo è stata una grande libreria di metodi comuni, come è stato menzionato finora, ma con una svolta. Il progetto della libreria ti permetterebbe di configurare in fase di compilazione quali pezzi sono inclusi come il progetto BusyBox . Con questo approccio, puoi avere un repository di libreria in stile sink di cucina, ma solo prendere gli strumenti necessari per la compilazione.

    
risposta data 23.06.2013 - 16:30
fonte
5

GitHub ha uno strumento piuttosto utile per il salvataggio di frammenti di codice link

Memorizza i tuoi snippet come repository git che puoi mantenere privati o utilizzare per condividere frammenti con altre persone.

    
risposta data 26.05.2013 - 14:09
fonte
3

A seconda delle dimensioni del team / progetto / azienda questa sarà una cosa piuttosto difficile da fare efficacemente, a meno che non sia già integrata nel tuo ambiente in qualche modo, e ogni soluzione che troverai (se la implementerai) costerà un po 'di soldi . (Potrebbe salvarti di più, ma non sarai in grado di misurare facilmente). Dovrai controllare se vale il prezzo. Tieni presente, inoltre, che le soluzioni riutilizzabili tendono a diventare astratte e spesso si adattano a molte situazioni, ma senza essere ottimali.

In ogni caso, se vuoi farlo per il codice prodotto da più di una persona, in un primo momento avrai bisogno della consapevolezza di tutti e della cooperazione. Questo include sviluppatori e manager.

Quindi dovrai assicurarti di conoscere l'ambito in cui vuoi farlo. Squadra? Progetto? Dipartimento? Azienda? A seconda della risposta, il tipo di codice che inserirai in tali soluzioni varierà, così come la granularità con cui personalizzi le DLL. Una volta che hai deciso su questo qualcuno (preferibilmente con un certo entusiasmo per l'idea - tu?) Dovresti sederti e iniziare a mettere una struttura in questo.

Tuttavia, la creazione di tali DLL non sarà sufficiente per fare il trucco. Per renderli utili dovrai pubblicizzarli (agli utenti e ai contributori) e mantenerli come qualsiasi altro software, il che di solito significa che devi metterli a capo di qualcuno per un lungo periodo di tempo. Avrai bisogno anche di una documentazione affidabile, che avrà anche bisogno di manutenzione. Con un po 'di fortuna e cooperazione potresti finire con alcune buone pratiche, ma può anche facilmente evolversi in un progetto a se stante, a seconda delle dimensioni e del numero di squadre coinvolte. E per questo avrai ancora bisogno del supporto di gestione.

    
risposta data 30.03.2013 - 15:50
fonte
3

Ho avuto un sacco di problemi, e la mia soluzione preferita è di pubblicare il codice in un repository abilitato per github / pubic web. risolve un sacco di problemi -

  1. facile accesso e facile condivisione. cvs / svn / enterprise-repos significa la verifica del progetto in più spazi di lavoro IDE e, talvolta, la necessità di cambiare area di lavoro o computer solo per fare riferimento a un piccolo snippet di codice.
  2. supponendo che questi frammenti di codice non siano pezzi di codice proprietari / classificati e siano variazioni della conoscenza disponibile pubblicamente, pubblicandoli su un repo pubblico come Github significa che altri lo guarderanno e potrebbero persino contribuire.
  3. pubblicare qualcosa di pubblico dominio sotto il tuo nome ha l'ulteriore pressione della reputazione. ricontrollerai e aggiornerai le cose, poiché riflette sulle tue abilità come programmatore.
  4. aggiornamenti. il fatto di conservare frammenti di codice in un repository è, se uno snippet non è stato utilizzato da molto tempo, potrebbe diventare obsoleto (contiene apis / libs obsoleti). esempio: snippet di codice java per leggere un file. avresti potuto trovare il modo migliore per farlo nel 2009, ma nel 2014 uscirà un nuovo file API che cambia tutto. il tuo frammento? ancora bloccato nel 2009. in un repo pubblico, le cose verranno aggiornate, sia da voi (perché il proiettile 3), i vostri compagni di squadra, o alcuni membri della popolazione generale del programmatore, e nel processo, potreste anche ricevere suggerimenti per aggiustare qualcosa che avresti potuto sbagliare per molto tempo.

Una cosa che vorrei raccomandare, non importa dove mantieni i tuoi frammenti, fai sempre roba su google prima di usarla. le cose cambiano tutto il tempo i frammenti salvati fanno risparmiare tempo, ma generano anche compiacimento .

    
risposta data 23.06.2013 - 12:14
fonte
2

Abbiamo un progetto separato "utilità" in cui archiviamo tutti questi piccoli metodi insieme ai test.

Quando un progetto richiede qualche utilità, aggiunge semplicemente il file sorgente con il metodo richiesto con "aggiungi come collegamento".

Ciò significa che non sono state aggiunte dipendenze del tempo di esecuzione (a meno che il file incluso ne abbia bisogno).

Il sistema ha funzionato bene, ma come tutti gli altri ha bisogno di diciplin su cosa sia un'utilità. Richiedere una copertura di prova elevata ha funzionato bene per noi e i test sono anche una buona documentazione di utilizzo. La scoperta è ancora un problema irrisolto per noi.

Una complessità con il progetto di utilità è decidere il livello di visibilità sugli articoli. Una regola empirica è che i metodi dovrebbero essere interni e le strutture dati pubbliche.

    
risposta data 31.03.2013 - 12:01
fonte
2

La mia azienda utilizza servizi web intranet-locali. Abbiamo alcuni servizi Web che vengono configurati come servizi Web interni comuni e quando un altro progetto deve accedere a uno dei servizi invia una richiesta http con un'interfaccia definita. Poiché si trova sulla intranet, ospitato nella stessa server farm, queste richieste sono molto veloci.

Ovviamente funziona solo con le app in Internet (e funziona solo in millisecondi quando si trova sulla stessa rete locale), ma presenta alcuni vantaggi davvero interessanti.

    
risposta data 01.04.2013 - 23:11
fonte
0

Di recente ho creato questo servizio: Snip2Code ( link ).

È un modo interessante per condividere solo i frammenti (non interamente librerie) con il tuo team. Rompe il solito punto di creare librerie comuni a cui fare riferimento in altri progetti, e secondo me questa è una visione preziosa.

Inoltre, ci sono molti scenari in cui l'uso di una libreria comune non si applica semplicemente: consideriamo ad esempio alcuni modelli di progettazione come Singleton, Strategy o Observer. Puoi creare librerie per supportare tali pattern ma ancora non c'è copertura al 100%.

Il vero bisogno è di avere uno strumento per condividere pratiche comuni tra la squadra. Ho provato ad usare gli schemi di Github ma sono bloccato dalla loro ricerca (davvero scarsa) e dal fatto che non posso condividerli solo tra la mia squadra e non con altri ...

(Disclaimer: sono uno dei fondatori di Snip2Code, ed ero - insieme ai miei co-fondatori - nella tua stessa mentalità qualche tempo fa: è per questo che abbiamo deciso di iniziare questo progetto !!)

    
risposta data 08.07.2013 - 18:49
fonte