Come fai a sapere quando dividere un metodo oggetto in 2 o più altri metodi?

6

So che questa è una domanda molto semplice, ma a volte mi trovo a dover lottare per capire quando suddividere un metodo a singolo oggetto in più metodi. Ad esempio, sto cercando di impostare un ACL utilizzando Zend_Acl e Zend_Auth, come illustrato in questo tutorial: link . Tuttavia, mi chiedo se il metodo My_Plugin_Auth :: preDispatch () debba richiamare le chiamate a un metodo chiamato authenticate () e un metodo chiamato authorize (), invece di avere tutto concentrato sotto preDispatch (). Stavo pensando che questo avrebbe reso il codice più leggibile e incapsulato la logica nelle sue parti più piccole, ma non sono sicuro che questa sia una ragione sufficiente.

    
posta blacktie24 07.03.2011 - 00:53
fonte

6 risposte

8

Senza aver letto l'articolo in questione, certamente si dovrebbe evitare la funzionalità di multiplexing nei metodi: l'autenticazione e l'autorizzazione sono cose molto diverse.

Quindi, solo su questa base, c'è una buona ragione.

his would make the code more readable ...not sure if this is reason enough.

Come ho speso anni a dire alle persone, non scriviamo il codice che i computer devono capire - scriviamo codice che le persone devono capire. Quindi se dividerlo in più metodi rende più semplice la non comprensione, allora è una buona idea.

    
risposta data 07.03.2011 - 01:00
fonte
3

Dal primo libro suggerito per programmatori su Stack Overflow - link

Ragioni valide per creare una routine

Ecco alcuni che potrebbero essere applicabili a questo caso.

  • Riduci la complessità
  • Evita il codice duplicato
  • Supporta la sottoclasse
  • Nascondi sequenze: le funzioni devono essere richiamate in un ordine particolare?
  • Per garantire che tutte le routine siano piccole? No

Un altro punto menzionato altrove è che una funzione dovrebbe "avere una coesione strong e funzionale - fare una sola cosa e farla bene".

Se la sequenza è importante potrebbe valere la pena creare una funzione wrapper che richiami i due nell'ordine corretto. In un approccio orientato agli oggetti, creare due funzioni separate per entrambe le operazioni, renderle private / protette e avere un metodo pubblico per chiamare i due in sequenza. In questo modo chiunque usi la tua classe non commetterà l'errore di chiamare solo una delle funzioni o di chiamarle nell'ordine sbagliato.

    
risposta data 07.03.2011 - 01:48
fonte
2

Penso che sia una buona idea suddividere funzioni più grandi in componenti logici e dai nomi dei due metodi suona molto ragionevole. Lungo la strada potrebbe essere necessario essere in grado di utilizzare quel metodo authorize per qualcos'altro senza la chiamata a authenticate e viceversa. Detto questo portandolo all'estremo può essere una cosa negativa, quindi sii ragionevole!

    
risposta data 07.03.2011 - 00:58
fonte
2

Questo è un concetto che ho imparato in Programmazione strutturata e che si applica ancora alla programmazione orientata agli oggetti. Ho visto molti "Spaghetti Object Oriented Code", con metodi che hanno un sacco di righe ...

Ecco le idee rapide su quando tagliare una singola funzione / metodo in più:

  • Regola empirica di 25 righe

Se il codice ha più di 25 righe, perché la mente del programmatore ha difficoltà a capire di più di quelle informazioni.

  • Regola del ciclo

Quando sei un "ciclo", con un obiettivo specifico, e quel codice è molto esteso. Per "loop", intendo "for", "foreach", "while", ecc. Un "for" con 3 righe di codice non può richiedere di essere messo in un metodo separato, ma un "for" con 35 righe di codice, significa spostarlo.

Esempio di origine (C #):

before_blah();
for (int k=0; k < list.Count; k++) {
  for_blah_1(k)
  ...
  for_blah_42(k)
}
after_blah();

Esempio dest. (C #):

before_blah();
this.iterateitems(); // <-- for goes there
after_blah();
  • Regola condizionale o alternativa

Simile, va per "blocchi" condizionali / alternativi come "if", "swith", "case", se alcune opzioni sono troppo estese, faccio un singolo metodo per quella opzione. Ci sono volte in cui, per ogni opzione, realizzo anche un singolo metodo, anche se non così grande.

Esempio di origine (C #):

switch (option) {
  case 0: 
    blah_0_0();
  break;
  case 1: 
    blah_1_0();
    ...
    blah_53_0();
  break;
} // switch

Esempio dest. (C #):

switch (option) {
  case 0: 
    cancelItem();
  break;
  case 1: 
    printItem();
  break;
} // switch
  • Regola funzionale

Per "funzionale", non significa "funzione", ma attività. Se hai 3 o più linee di codice consecutivo, che condividono un obiettivo comune, potresti voler fare un metodo separato.

Esempio di origine (C #):

FileStream F = new FileStream();
F.Path = parameterPath;
F.Options = myOptions;
F.Reset();

do_something();

F.Close();

Esempio dest. (C #):

FileStream F = this.PrepareFileStream(parameterPath, myOptions);

do_something();

F.Close();

Naturalmente, alcune di queste linee guida sono più soggettive che logiche.

Solo i miei 2 centesimi ...

    
risposta data 07.03.2011 - 18:00
fonte
1

La necessità di riutilizzare è una ragione ovvia. La leggibilità è sempre utile, ma sto iniziando a usare la teoria di Quanto posso tenere nel mio cervello in una volta? Rompi un pezzo del codice in un altro metodo e una volta che lo fai funzionare, puoi dimenticarlo. Mi aiuta a concentrarmi.

    
risposta data 07.03.2011 - 04:06
fonte
1
  1. È così lungo che non riesco a vederlo senza doverlo sfogliare?
  2. Fa più di una cosa alla volta?
  3. È difficile dire cosa sta facendo?
  4. Mostra segni di riutilizzo copia-incolla?
  5. Ho un motivo perfettamente valido per ridefinire il metodo in questo momento , o dovrei fare qualcos'altro (come correggere un difetto)?
risposta data 07.03.2011 - 13:19
fonte

Leggi altre domande sui tag