Come decidi quale codice inserire in una funzione?

2

Ho iniziato con una sceneggiatura di poche centinaia di righe. Più tardi, mi sono reso conto che volevo un altro script che avrebbe richiesto gran parte dello stesso codice. Ho deciso di avvolgere alcune aree dello script originale che sarebbero state condivise, in definizioni. Quando stavo decidendo esattamente cosa dovrebbe essere in una funzione, mi sono imbattuto in varie cose da considerare:

  1. Cosa devo impostare come parametri di input? Se fosse necessario qualcosa nella funzione, probabilmente dovrei richiederlo come parametro, giusto? O dovrei dichiararlo all'interno della funzione stessa?

  2. Se la funzione x richiede sempre l'output della funzione y, ma la funzione y talvolta è necessaria da sola, la funzione X dovrebbe includere il codice della funzione y o semplicemente chiamare la funzione y?

  3. Immagina un caso in cui ho 5 funzioni che chiamano tutte una funzione 'sub' (il sub è essenziale per queste 5 funzioni per completare il loro lavoro). Se "sub" dovrebbe sempre restituire lo stesso risultato, allora le chiamate multiple da queste funzioni genitore non duplicheranno lo stesso lavoro? Se sposto la chiamata a "sub" al di fuori delle 5 funzioni, come posso essere sicuro che "sub" sia chiamato prima della prima chiamata a una delle 5 funzioni?

  4. Se ho un segmento di codice che produce sempre lo stesso risultato e non è richiesto più di una volta nella stessa applicazione, normalmente non lo metterei in una funzione. Tuttavia, se non è una funzione, ma è successivamente richiesta in un'altra applicazione, dovrebbe diventare una funzione?

Scusa se queste domande sono troppo vaghe, ma ritengo che dovrebbero esserci alcune linee guida generali. Non ho programmato per molto tempo e sono rimbalzato tra OOP e funzionale, ma non mi sono mai ricordato di aver letto nulla che spiegasse ciò. Potrebbe semplicemente essere una questione di preferenze personali?

    
posta imagineerThis 31.05.2013 - 21:29
fonte

4 risposte

2
  1. ci sono 2 modi per passare i dati in una funzione: parametri o globali, in piccoli script globali sono accettabili ma davvero cercano di evitarli

  2. è più facile estrarre semplicemente questo è anche meglio quando devi cambiarlo più tardi

  3. puoi utilizzare l'inizializzazione pigra qui:

    var subresult=undefined
    
    function sub(){
        if(subresult===undefined){
            subresult=//calculate...
        }
        return subresult;
    }
    
  4. ci sono 2 principi in competizione qui SRP e YAGNI:

    A. Principio della singola responsabilità significa essenzialmente che ogni funzione dovrebbe fare una singola cosa e farlo correttamente

    B. Non hai intenzione di averne bisogno: non perdere tempo in cose che potrebbero o non potrebbero essere necessarie in futuro, concentrati su ciò di cui hai bisogno ora

risposta data 31.05.2013 - 22:01
fonte
9

Attualmente stai pensando che le funzioni siano solo un contenitore di codice che viene riutilizzato da qualche parte. Questo è un inizio quando si impara come costruire le funzioni, ma non è il modo migliore.

Un altro punto di vista è usare le funzioni per costruire astrazioni. Hai scritto di avere uno script con poche 100 righe - bene. Ora hai blocchi all'interno di questo script facendo una certa attività secondaria. Ognuno di questi blocchi appartiene a una funzione a sé stante. Il nome della funzione dovrebbe essere auto-esplicativo e dirti cosa è questa sottotask. Quando si evitano le variabili globali e gli effetti collaterali, diventa evidente quali parametri saranno necessari alle funzioni e che cosa devono restituire.

In questo modo, le tue funzioni stanno diventando gli elementi costitutivi della tua applicazione. Questo è per lo più indipendente dalla frequenza con cui vengono riutilizzati e indipendentemente dalla frequenza con cui vengono chiamati.

If function x always requires the output of function y, but function y sometimes is needed alone, should function X include the code of function y or simply call function y?

y è una sottoattività singola all'interno di x, qualcosa per cui puoi dare un nome separato, quindi dovrebbe essere chiaramente nella sua funzione - indipendentemente dal fatto che sia necessario o meno da solo !

Imagine a case where I have 5 functions that all call a function 'sub' (sub is essential for these 5 functions to complete their work). If 'sub' always is supposed to return the same result, then wouldn't multiple calls from these parent functions duplicate the same work? If I move the call to 'sub' outside of the 5 functions, how can I be sure that 'sub' is called before the first call to any of the 5 functions?

Innanzitutto, se c'è la stessa cosa calcolata due volte, è davvero importante nel tuo caso? Non è necessario ottimizzarlo finché non si è verificato un collo di bottiglia prestazionale. In secondo luogo, se in questo caso hai davvero un collo di bottiglia nelle prestazioni, c'è la tecnica di memoization , che risolverà esattamente questo problema.

If I have a segment of code that always produces the same result, and isn't required more >than once in the same application, I normally wouldn't put it in a function.

Questo è esattamente ciò che dovresti fare: metterlo in una funzione, non allo scopo di riutilizzarlo, ma allo scopo di creare un'astrazione.

    
risposta data 31.05.2013 - 23:13
fonte
2
  1. In Pulisci codice , Robert Martin sostiene che un numero inferiore di parametri è migliore. Valuta se qualcosa dovrebbe essere una variabile di istanza invece di un parametro. Inoltre, vedi Preserve Whole Object in Refactoring di Martin Fowler.

  2. Funzione di chiamata y. Non ripetere te stesso (DRY) come raccomandato in Programmatore pragmatico (Hunt e Thomas)

  3. Non sono sicuro di cosa intendi con "restituisce sempre lo stesso risultato". Vuoi dire che lo stesso risultato viene restituito per gli stessi parametri di input (deterministici)? Stai chiedendo informazioni sul caricamento lento?

  4. Prima di leggere Pulisci codice , ero riluttante a creare piccole funzioni che venivano utilizzate una sola volta. Ora lo faccio spesso. Considerare l'estrazione di una funzione se si dispone di una funzione lunga con diversi blocchi che rappresentano i passaggi secondari della funzione. Il segno rivelatore è un commento che dice qualcosa come "Calcola le vendite mensili". Probabilmente dovresti estrarre il blocco di codice in una funzione chiamata calculateMonthlySales .

risposta data 31.05.2013 - 22:00
fonte
1

Non ci sono ricette per la logica, ma risponderò alle tue domande specifiche:

Q: Cosa devo impostare come parametro di input?

A: le cose necessarie per fare il calcolo

D: Se fosse necessario qualcosa nella funzione, probabilmente dovrei richiederlo come parametro, giusto?

A: sì, oppure puoi scaricarlo da un file o database

D: Se la funzione x richiede sempre l'output della funzione y, ma la funzione y talvolta è necessaria da sola, la funzione X dovrebbe includere il codice della funzione y o semplicemente chiamare la funzione y?

A: chiama semplicemente y

Q: Immagina un caso in cui ho 5 funzioni che chiamano tutte una funzione 'sub' (il sub è essenziale per queste 5 funzioni per completare il loro lavoro). Se "sub" dovrebbe sempre restituire lo stesso risultato, allora le chiamate multiple da queste funzioni genitore non duplicheranno lo stesso lavoro?

A: se sub restituisce sempre lo stesso risultato, quindi non viene eseguito alcun lavoro.

Q: Se mi muovo 'sub' al di fuori delle 5 funzioni, come posso essere sicuro che 'sub' sia chiamato prima della prima chiamata a una delle 5 funzioni?

A: non era già secondario alle 5 funzioni? ... Non chiamare sub da una di queste funzioni. Chiamalo nel programma principale prima di chiamare le 5 funzioni.

D: Se ho un segmento di codice che produce sempre lo stesso risultato e non è richiesto più di una volta nella stessa applicazione, normalmente non lo inserirò in una funzione. Tuttavia, se non è una funzione, ma è successivamente richiesta in un'altra applicazione, dovrebbe diventare una funzione?

A: Se è abbastanza complesso. Mettilo in una funzione. Se altre app ne hanno bisogno, condividi la libreria.

    
risposta data 31.05.2013 - 21:57
fonte

Leggi altre domande sui tag