DRY o non DRY in SDK

1

Sto dando un contributo a un progetto opensource da uno dei principali provider di hypervisor e ho notato che c'è un sacco di ripetizioni.

Di seguito è ciò che intendo con questo, immagina di farlo più volte nella stessa classe e poi in altre classi.

def get_some_stuff_type_A(self, name):
    """The same Text
    """
    result = call_the_same_method(name=name, type=A)
    return result

def get_some_stuff_type_B(self, name):
    """The same Text
    """
    result = call_the_same_method(name=name, type=B)
    return result

def get_some_stuff_type_C(self, name):
    """The same Text
    """
    result = call_the_same_method(name=name, type=C)
    return result

Questo dovrebbe essere schiacciato in un metodo con un altro parametro di type per renderlo ASCIUTTO?

O questo è permesso visto che questo è un SDK e questo fornisce una migliore visibilità su tutta la linea quando si lavora con esso? Sebbene sia ancora una brutta ripetizione.

    
posta MMT 23.11.2018 - 17:18
fonte

2 risposte

4

Questa non è una violazione di DRY. È una facciata che nasconde i dettagli di implementazione che get_some_stuff_type_A e get_some_stuff_type_B utilizza lo stesso metodo sottostante. Questo è spesso un buon progetto API, poiché l'implementazione potrebbe cambiare in futuro per utilizzare metodi diversi senza influire sull'interfaccia. (Che sia un buon design in questo caso particolare è difficile da dire dato che l'esempio è così astratto, ma il principio va bene.)

Per fare un esempio più concreto:

def suspend_user():
     set_user_state('suspended')
def delete_user():
     set_user_state('deleted')
private def set_user_state(state)
     set_state_enum_in_database(state)

Potresti semplicemente esporre set_user_state(state) direttamente e lasciare che il chiamante fornisca il valore dello stato, giusto? Ma cosa succede se si desidera modificare l'implementazione per eliminare effettivamente il record dal database? Oops, non puoi farlo ora. O cosa succede se delete_user dovrebbe prendere un flag che indica se l'utente è cancellato in modo permanente? Troppo tardi. Esponendo l'enum di stato nell'API hai abbinato l'API a una particolare implementazione.

D'altra parte ci possono essere contesti in cui il secondo approccio è migliore. Diciamo che c'è una routine di rendering del testo:

def print_letter_A():
    print_character('A')
def print_letter_B():
    print_character('B')

In questo caso non c'è alcun valore ad avere metodi individuali per ogni lettera, quindi potresti semplificare l'API per esporre solo print_character(char) .

Quindi la risposta effettiva alla tua domanda dipende da cosa è "roba".

DRY è un buon principio in generale, ma a volte è frainteso. Non dice che dovresti comprimere il codice per contenere il numero più basso di token. Dice che la stessa informazione dovrebbe essere rappresentata solo una volta. Ma nel caso di una facciata API hai due diversi tipi di informazioni: come appare l'interfaccia API e come viene effettivamente implementata. Questi presunti devono essere diversi ed essere in grado di cambiare indipendentemente, altrimenti hai un accoppiamento stretto.

    
risposta data 24.11.2018 - 09:55
fonte
2

Voterò per lo schiacciamento, purché il codice faccia effettivamente la stessa cosa.

A mio parere, il codice dovrebbe esprimere l'intento. Se è lo stesso intento, dovrebbe eseguire lo stesso codice, non più copie di esso.

Cercherò anche di pensare all'interfaccia. La sua ergonomia non sembra eccezionale, con metodi ripetitivi simili. OTOH se gli utenti chiamano per lo più un solo metodo con un nome espressivo, potrebbe essere un buon approccio.

    
risposta data 23.11.2018 - 23:18
fonte

Leggi altre domande sui tag