Codice Python liberamente accoppiato con Dependency Injection
Il software deve essere flessibile per rispondere al cambiamento. Dependency injection è una tecnica per gestire le dipendenze tra componenti software. È un modello di progettazione che utilizza l'inversione del controllo per fornire la possibilità di scambiare componenti per test o altri scopi senza modificare nessun'altra parte del sistema.
L'idea principale alla base dell'iniezione di dipendenza è trasferire la responsabilità di fornire servizi da funzioni di costruzione o metodi di istanziazione diretta su altri oggetti. In altre parole, a un oggetto vengono assegnate le sue dipendenze invece di crearle. In questo modo, se vogliamo aggiungere nuove funzionalità, non dobbiamo modificare il codice esistente ma, invece, passare nuove dipendenze al suo interno.
Creazione di astrazioni con interfacce
Ci sono tre passaggi per scrivere codice Python liberamente accoppiato con dependency injection. Il primo passaggio consiste nell'identificare le dipendenze necessarie al codice, il secondo passaggio consiste nel creare interfacce per ogni dipendenza e il terzo passaggio consiste nel passarle all'oggetto dipendente tramite i relativi parametri del costruttore o del metodo.
Recentemente, ho implementato funzionalità che richiedevano un codificatore e un decodificatore di byte per manipolare i dati aziendali ( ho semplificato la sua implementazione per motivi di leggibilità ). Ho sottratto le loro responsabilità alle interfacce. Python non ha una parola chiave dell'interfaccia come Golang, ma puoi replicare la funzionalità dell'interfaccia con la libreria ABC .
Concentrandosi sull'interfaccia IPacketEncoder, una classe codificatore concreta deve implementarla. I requisiti aziendali iniziali richiedevano la codifica di tutti i tipi e il riempimento delle stringhe con la loro lunghezza. Fortunatamente, Python fornisce la libreria struct per svolgere la maggior parte del duro lavoro.
Implementazione dell'iniezione di dipendenza
La encode_namefunzione è una semplice implementazione per la creazione di un payload codificato con il nome specificato. Prende un IPacketEncoderoggetto e una stringa come parametri.
I due dettagli chiave dell'implementazione stanno usando l' IPacketEncoderinterfaccia invece della PaddedPacketEncoderclasse concreta ed encoderè un argomento piuttosto che essere inizializzato all'interno della funzione. Questa è l'iniezione di dipendenza. Poiché IPacketEncoderè passato, può essere facilmente esteso, modificato o dotato di uno stub , mantenendo così il sistema liberamente accoppiato.
Poche settimane dopo, c'era un nuovo requisito per un codificatore per gestire le codifiche con terminazione null. Fortunatamente, grazie all'implementazione esistente, può essere facilmente implementato.
NullTerminatedPacketEncoderessenzialmente aggiunge NULL_BYTEdopo ogni stringa codificata. Tornando alla encode_namefunzione, un'istanza di NullTerminatedPacketEncoderè un argomento codificatore valido poiché NullTerminatedPacketEncoderimplementa l' IPacketEncoderinterfaccia in modo simile a PaddedPacketEncoder.
Se l'inserimento delle dipendenze non è stato utilizzato qui, potrebbe risultare in un codice strettamente accoppiato e difficile da modificare, ad esempio:
Se è necessario un nuovo encoder, la encode_namefunzione dovrà essere cambiata quasi interamente insieme ai suoi test, allungando i tempi di consegna. Quel che è peggio, potrebbe causare effetti collaterali nascosti, soprattutto se lo sviluppatore originale non è più disponibile.
Per concludere, fornirò un esempio meno semplicistico usando questa tecnica. SocketServiceè responsabile della decodifica di un codice operazione, della chiamata del relativo gestore e della restituzione del risultato. Tutti i suoi tipi di argomenti sono astrazioni di interfaccia, incluso il suo costruttore. La CLI è responsabile della determinazione del codificatore da utilizzare, ad esempio NullTerminated o Padded, e del trasferimento della sua istanza alla SocketServiceclasse.
Man mano che i progetti continuano a crescere, si consiglia di utilizzare un framework di dependency injection per "iniettare" automaticamente queste dipendenze, come Dependency Injector .
Si spera che questo dimostri come scrivere codice Python liberamente accoppiato con l'iniezione di dipendenza. A molti sviluppatori Python non piace l'iniezione di dipendenza perché ritengono che non sia "pitonica", ma direi che i suoi vantaggi non possono essere screditati, specialmente quando è presente in così tanti altri linguaggi di programmazione.
Grazie per aver letto . Se vuoi connetterti con me, puoi trovarmi su Linkedin o Github .

![Che cos'è un elenco collegato, comunque? [Parte 1]](https://post.nghiatu.com/assets/images/m/max/724/1*Xokk6XOjWyIGCBujkJsCzQ.jpeg)



































