Qual è lo scopo della scrittura di funzioni e metodi? Quando dovresti creare uno snippet di codice in una funzione o un metodo?

4

Ho un disaccordo filosofico con uno dei miei colleghi di lavoro, e sto cercando di tornare alle origini qui. Qual è lo scopo di un metodo?

In questa domanda, considera questo esempio. Sono stato criticato per aver scritto i seguenti due metodi. Mi piacerebbe dare l'avvertenza che questo è un esempio di bambino bollito, che c'erano altri punti nel mio codice che erano più complicati ma simili.

L'esempio del bambino

class UI:
    def __init___(self):
        self.thingsCheckBox = # checkbox widget
        self.moreThingsCheckBox = # checkbox widget

def wantShowThings(self):
    return self.thingsCheckBox.checkState()

def wantShowMoreThings(self):
    return self.moreThingsCheckBox.checkState()

Quindi, il mio collega di lavoro mi ha chiesto di scrivere questi due metodi. Alla fine, sono stato costretto a rimuovere questi due metodi (dato che non hanno superato la revisione del codice). E questo alla fine significava ...

La mia versione

if ui.wantShowThings():
    # do stuff...

if ui.wantShowMoreThings():
    # do more stuff...

La sua versione (che alla fine ha vinto)

 if ui.thingsCheckBox.checkState():
     # ...

 if ui.moreThingsCheckBox.checkState():
    # ...

Qual è lo scopo di scrivere quei metodi?

  • riutilizzo: penso che siamo tutti d'accordo sulla riusabilità. Se un bit di codice viene copiato e incollato più volte, dovrebbe essere inserito in una funzione o in un metodo in modo tale che se il codice cambia, è sufficiente modificarlo in un unico punto. Il mio collaboratore sostiene che la riusabilità è la ragione per cui solo scrivere qualcosa in una funzione. Il mio collega ha detto che se una funzione non viene chiamata più di una volta, dovrei "allineare" la logica (scriverla nel posto in cui è utilizzata) e scrivere un commento. I metodi "corti" sono "inutili" e servono ad aumentare il "codice spaghetti". "Smettila di farmi sobbalzare per capire la logica".

Credo che le funzioni di scrittura abbiano altri scopi:

  • incapsulamento: nascondi l'implementazione della tua classe. Questo porta il tuo pensiero ad un livello più alto e astrae le parti concrete del tuo codice. Nel mio esempio precedente, non importa con wantShowThings () indipendentemente dal fatto che l'implementazione sottostante sia una checkbox, un radio button o anche una chiamata al server. Stiamo pensando in modo più astratto di una casella di controllo. Stiamo pensando "se vogliamo mostrare le cose".

  • documentazione: penso che il codice stesso possa servire da documentazione. So che ci sono persone piuttosto radicali che pensano che i commenti siano completamente inutili. Anche se non sono così estremo, sono solidale con la filosofia. Perché scrivere un commento quando puoi refactoring in un metodo con un nome significativo? Nel mio esempio, non ho bisogno di un commento # This returns true if we want to show things , è nel nome del metodo.

Credo di avere una moltitudine di letteratura che supporta il mio pensiero. "Clean Code", CodingHorror. Ho frequentato un corso con David Cheriton di Stanford, che sicuramente è stato dalla mia parte.

    
posta SharkCop 15.03.2016 - 19:32
fonte

3 risposte

4

Lo scopo principale di un metodo (oltre al riutilizzo) è

Creazione di un'astrazione utile introducendo un nome significativo e scelto con cura.

(L'hai chiamato "incapsulamento" e "documentazione", entrambi non sbagliati, ma non completamente il termine che meglio si adatta a IMHO).

Forse puoi convincere il tuo collega dicendogli che la sua versione viola chiaramente la " Legge di Demeter ". O forse gli dica solo che la sua versione è mediocre, la tua è decisamente migliore (a patto che il nome della funzione renda davvero più chiaro lo scopo) ;-))

    
risposta data 15.03.2016 - 20:36
fonte
3

My co-worker said that if a function isn't called more than once, I should "inline" the logic (write it in the place its used) and write a comment. "Short" methods are "useless" and serve to increase the "spaghetti code". "Stop making me jump around to figure out the logic".

E d'altra parte:

I believe that writing functions serves other purposes:

Encapsulation...

Documentation...

E alla fine, hai ragione entrambi. Il tuo collega ha ragione nel fare un metodo che oscura solo una riga di codice chiamata una volta può offuscare e non fornisce alcun valore. Hai ragione che una funzione ben fatta può chiarire cosa sta succedendo e creare un'astrazione in modo che i dettagli di implementazione possano essere modificati liberamente.

Quale è meglio cade esattamente nel territorio "dipende". Non solo su ciò che viene astratto, ma su come viene usato, come sarà usato, l'abilità dei programmatori, l'oscurità del dominio ... dozzine di cose. Sopporti i vantaggi / svantaggi di una opzione rispetto all'altra e fai la tua ipotesi migliore sulla base delle conoscenze a tua disposizione.

A volte indovinerai male e arriverete al refactoring. Questo è parte integrante dell'arte della programmazione.

    
risposta data 15.03.2016 - 20:40
fonte
1

Penso che tu abbia già risposto alla tua domanda. Ho avuto lo stesso pensiero mentre stavo iniziando a sviluppare per Android. Ho avuto questa variabile membro nella mia classe CheatActivity

public static final String EXTRA_ANSWER_SHOWN = "com.sabernova.geoquiz.answer_shown";

... e anche questo metodo:

public static boolean wasAnswerShown(Intent data) {
    return data.getBooleanExtra(EXTRA_ANSWER_SHOWN, false);
}

L'oggetto dati è stato ricevuto nella classe QuizActivity che è anche il programma di avvio per la mia app e non ho capito perché l'autore volesse includere un metodo e il tag stringa per Boolean extra nella seconda attività . Perché non accedervi direttamente?

C'erano due cose:

  1. Il Boolean extra viene creato e quindi appartiene a CheatActivity e, quindi, il tag deve risiedere entro CheatActivity - dati incapsulanti.
  2. Diciamo che ho usato la dichiarazione solo una volta. Non significa che sarà sempre così. Espanderò la mia app in futuro e ciò significa che potrei usarla più di una volta. Oppure di cambiare il tag stringa nella classe CheatActivity . Ora, devo andare avanti e cambiare anche tutti gli avvistamenti della stringa all'interno di QuizActivity . Questo sarà frenetico a lungo termine e potrebbe essere risolto inserendo la frase giusta all'interno di una funzione ben definita: Riutilizzare.

Quindi, in poche parole, la creazione delle funzioni corrette significa che qualsiasi modifica nel codice effettivo non interromperà l'intero sistema e causerà un sacco di codice di riscrittura poiché la funzione funge da interfaccia attraverso che, possiamo eseguire codice e ottenere le cose necessarie.

    
risposta data 15.03.2016 - 20:03
fonte

Leggi altre domande sui tag