Divisione del codice client / server

Sto sviluppando un’applicazione client / server in golang, e ci sono alcune quadro logiche che esistono sia su client che su server (la lista è limitata)

Mi piacerebbe assicurarmi che un certo codice per queste quadro sia incluso SOLO nella parte server ma NON nel client (il saggio è bello, ma non così importante).

Il pensiero ingenuo sarebbe quello di fare affidamento sull’eliminazione del codice morto, ma dalla mia breve ricerca non è un modo affidabile per gestire il compito … go build semplicemente non eliminerà il codice morto dal fatto che potrebbe essere stato usato tramite riflessione ( a nessuno importa che non fosse e non c’è alcuna opzione per sintonizzarlo)

Un approccio più solido sembra dividere il codice in pacchetti diversi e importarlo in modo appropriato, questo sembra affidabile ma troppo complicato il codice che ti obbliga a dividere fisicamente determinate quadro tra diversi pacchetti e tenerlo costantemente presente …

E infine ci sono i tag di compilazione che consentono di avere più file sotto lo stesso pacchetto costruito in modo condizionale per client e server

    La motivazione con l’utilizzo dei tag di build è che voglio mantenere il codice il più pulito ansible senza introdurre quadro sintetiche

    Caso d’uso: esistono alcune routine di crittografia, il client funziona con la chiave pubblica, il server funziona con il privato … Il codice appartiene logicamente alla stessa entity framework

    Quale opzione sceglieresti e perché?

    Questa “eliminazione del codice morto” è già stata eseguita, in parte, dallo strumento go. Lo strumento go non include tutto da pacchetti importati, solo ciò che è necessario (o più precisamente: esclude cose che possono rivelarsi irraggiungibili).

    Ad esempio questa applicazione

     package main; import _ "fmt"; func main() {} 

    ha come risultato un file eseguibile di dimensioni minori di quasi 300 KB (su Windows amd64) rispetto al seguente:

     package main; import "fmt"; func main() {fmt.Println()} 

    Le cose escludibili includono funzioni, tipi e anche variabili non esportate ed esportate. Ciò è ansible perché anche con la reflection non è ansible chiamare una funzione o un tipo di “istanza” o fare riferimento alle variabili del pacchetto solo avendo il loro nome come valore di string . Quindi forse non dovresti preoccupartene più di tanto.

    Modifica: con Go 1.7 rilasciato, è ancora meglio: leggi post sul blog: binari Smaller Go 1.7

    Quindi, se progetti bene i tuoi tipi e funzioni e non crei registri “giganti” in cui enumerati funzioni e tipi (che generano esplicitamente dei riferimenti a loro e quindi li rendono inestinguibili), i binari compilati conterranno solo ciò che viene effettivamente utilizzato da pacchetti importati.

    Non suggerirei di usare i tag di compilazione per questo tipo di problema. Usandoli, avrai una responsabilità in più per mantenere te stesso le dipendenze di pacchetti / file che altrimenti sono fatte dallo strumento go.

    Non è necessario progettare e separare il codice in pacchetti per rendere più piccoli i file eseguibili di output. Dovresti progettare e separare il codice in pacchetti basati sulla logica.

    Vorrei andare con la separazione di cose in pacchetti quando è davvero necessario, e importare in modo appropriato. Perché questo è davvero ciò che vuoi: un codice pensato solo per il client, alcuni solo per il server. Potresti dover pensare un po ‘di più durante la fase di progettazione e codifica, ma almeno vedrai il risultato (ciò che effettivamente appartiene / viene compilato nel client e nel server).