Il modo pythonic: sostituire le interfacce con ducktyping vs inheritence

-1

tldr: ho classi simili ai consumatori che richiedono un certo numero di informazioni per svolgere il loro lavoro. È un tipo di "tutto o niente": i "produttori" che forniscono loro dati devono fornire tutte le informazioni necessarie o ci sarà un problema. Voglio fornire alcune affermazioni per assicurarmi che tutto sia presente. So che Python è normalmente un fan della tipizzazione delle anatre, ma poiché ho bisogno di avere tutti i dati presenti in tutti i casi, penso che sarebbe più facile fare una classe base che i produttori devono implementare, e poi affermare tramite instanceof . Questa è una scelta ragionevole o è ancora la preferenza per la digitazione?

Sfondo

Immagino che un po 'di background sia utile per assicurarmi che non cadessi vittima del problema XY . Sto lavorando su un sistema per gestire la struttura del database tramite il controllo della versione (un sistema di migrazione del database). Ho alcune classi che confrontano le definizioni delle tabelle per vedere se qualcosa è cambiato. Le definizioni delle tabelle stesse possono provenire da una varietà di posizioni: può provenire dalle definizioni memorizzate nei file di testo, può provenire dalla lettura del database attuale, ecc ... Quindi ho alcune classi responsabili del caricamento della struttura del database da vari fonti (produttori), e poi altre classi che prendono quelle definizioni e cercano le differenze (consumatori).

Ho brevemente pensato di coinvolgere una terza entità per memorizzare la definizione della tabella effettiva e che sarebbe stata costruita dai produttori e trasmessa ai consumatori. Tuttavia, non penso che ci sia effettivamente bisogno di essere un qualsiasi comportamento associato a una classe del genere: funzionerebbe semplicemente come una mera porta-dati tra i due che avrebbe solo alcune proprietà su di esso. Di conseguenza, penso che preferirei ignorarlo, poiché non ha responsabilità reali.

Invece (nel gergo di altri linguaggi di programmazione), il mio pensiero era di avere un'interfaccia semplice che definisse quella definizione di tabella. Le classi di produttori implementano l'interfaccia, leggono le rispettive fonti e compilano i dati di conseguenza. I consumatori quindi accettano semplicemente qualsiasi oggetto che implementa l'interfaccia di definizione della tabella. Ovviamente, però, questo non è il modo Python.

Avendo fatto alcune letture sull'argomento, sembra che la digitazione anatra sia la soluzione preferita per questo problema. Nel mio caso però, mi sembra che potrebbe non essere la soluzione migliore. La ragione principale è perché non prevedo alcuna necessità di flessibilità nei parametri dei dati richiesti. Se ho sempre bisogno della stessa mezza dozzina di proprietà, ritengo che violerebbe DRY per verificare che tutto i parametri sono presenti ogni volta che ne ho bisogno.

Piuttosto, il mio pensiero è di lasciare che la definizione della tabella sia una classe base che i produttori aggiungono alla loro catena ereditaria e che definisce le proprietà che devono essere fornite. I consumatori faranno semplicemente una semplice dichiarazione di instanceof prima di fare le loro cose.

È un approccio ragionevole a questo problema in Python, o ci sono modi migliori?

    
posta Conor Mancone 31.07.2017 - 15:27
fonte

1 risposta

1

La tua logica sembra ragionevole. In questo modo: come utente, non voglio dover leggere l'intero codice per capire quale interfaccia ti aspetti. È meglio fornire semplicemente una classe base o una classe base astratta da cui ereditare e riempire gli spazi vuoti (inoltre, è possibile comunicare la semantica dell'interfaccia dalla definizione della classe base).

Questo sembra un modo più semplice per comunicare i requisiti. Non so se il dattilografia sia ancora così popolare ora che abbiamo Python 3 (ha persino introdotto i tipi!) Quindi non lasciare che le convenzioni / filosofia del linguaggio ti facciano troppo.

In una lingua come Java, direi qualcosa di simile

void function(Somethingable x){
   do something that requries x to be Somethingable
}

È davvero la stessa idea. Avrei cercato "qualcosa di utile" nei Javadoc e implementato / sottoclasse di conseguenza.

    
risposta data 04.08.2017 - 04:51
fonte