Come utilizzare il refactar per diverse funzioni simili?

1

Mi è stato assegnato un refactoring.

Abbiamo diversi moduli con funzioni simili con alcune differenze. Il mio compito è estrarre porzioni di codice comuni per il principio DRY.

Sono un po 'perso come farlo.

Potrei semplicemente tagliare e incollare frammenti di codice simili, estraendoli in funzioni separate, ma se lo faccio in questo modo meccanicamente, allora le dichiarazioni e l'uso delle variabili locali delle funzioni frammentate possono capitare di cadere in funzioni diverse, cosa potrebbe portare a codice non valido.

Potresti fare alcuni consigli pratici su come gestire questo problema. Vorrei una guida passo-passo sul refactoring di tale codice con variabili locali.

E inoltre: per qualche ragione il mio capo vuole che il codice risultante non sia orientato agli oggetti. Penso che questo possa essere risolto passando frammenti di codice come puntatori di funzioni.

Non riesco a mostrare un esempio di codice per la mia domanda, perché il codice reale è closed-source e non riesco a scrivere un esempio minimale, perché l'intero problema riguarda le funzioni lunghe.

Un'altra nota: scriviamo in Perl.

    
posta porton 05.03.2017 - 19:19
fonte

3 risposte

3

Dovresti cercare ciò che hanno in comune, ad es. aprono tutti una connessione SQL, hanno tutti bisogno di gestire gli errori e chiudere le risorse alla fine, tutti chiamano alcune API nel mezzo, ecc. Quindi concentrarsi sulla separazione di ciò che è costante da ciò che è variabile.

Ci sono alcuni schemi che aiutano a risolvere questo problema. Considera

Pattern di strategia

Modello modello

    
risposta data 05.03.2017 - 20:28
fonte
2

Scopri quali parti sono comuni e separa le parti non comuni in funzioni separate. Quindi combinali.

Supponi di avere due funzioni:

def foo_y(x):
   <fragment A dealing with x>
   <fragment X>

def foo_z(x):
   <fragment A dealing with x>
   <fragment Y>

Ora è facile creare funzioni fragment_a , fragment_x , fragment_y e combinarle in foo_x e foo_y .

Potresti avere una struttura a strati:

def foo_y(x):
   <fragment A dealing with x>
   b = <fragment X>
   <fragment B dealing with b>

def foo_z(x):
   <fragment A dealing with x>
   b = <fragment Y>
   <fragment B dealing with b>

Estrai fragment_x e fragment_y s funzioni.

Ora puoi scrivere:

def parametric_foo(x, handler_of_b):
  <fragment A>
  b = handler_of_b(...)
  <fragment B>

La combinazione di questi due approcci dovrebbe aiutarti con la maggior parte del compito.

    
risposta data 05.03.2017 - 20:58
fonte
0

Può essere fatto sostituendo tutte (o la maggior parte delle) variabili locali con una struttura / record (hash in Perl) con queste variabili come membri.

Quindi è sufficiente passare alla funzione di frammento estratto un puntatore alla struttura, senza la necessità di passare (fare riferimento a) ogni variabile locale.

Questa strategia semplifica l'estrazione di frammenti di codice in funzioni separate.

Questo approccio assomiglia anche alla programmazione orientata agli oggetti: la struttura che racconto è come un oggetto (il cui scopo è quello di mantenere i dati intermedi per il calcolo della funzione refactored).

    
risposta data 09.03.2017 - 15:50
fonte

Leggi altre domande sui tag