2 metodi che sono uguali al 75%? [chiuso]

0

Ho un codice che viola il principio DRY e vorrei consolidare il più possibile 2 metodi, ma il problema che sto affrontando è che hanno alcune differenze, direi che sono circa il 75% lo stesso , ma l'altro 25% è diverso in certe aree. Quali tipi di schemi di progettazione o approcci di progettazione posso fare per trasformare 2 metodi in 1 o almeno limitare il codice necessario in ciascuno, in modo che diventino più scalabili e manutenibili?

    
posta xaisoft 27.02.2015 - 06:42
fonte

3 risposte

6

È difficile rispondere senza guardare il codice. Tuttavia, è chiaro che questi metodi stanno cercando di fare troppo. Stanno quasi certamente violando l'SRP.

Suggerisco di iniziare osservando dove i metodi sono diversi e perché. Forse potresti utilizzare il metodo di iniezione per inserire codice diverso nel metodo, in base a chi o che cosa lo chiama.

Fondamentalmente, per quanto riguarda il codice di refactoring come questo, dovresti cercare di capire perché il codice è lo stesso e perché è diverso. Una volta comprese queste due cose, puoi quindi considerare questi metodi in modo che non provino più a fare troppo.

    
risposta data 27.02.2015 - 06:56
fonte
3

Troppo difficile da valutare senza avere un segmento di codice da analizzare.

Il consolidamento dei metodi dovrebbe essere applicato qui, hai solo bisogno di tenere a mente alcuni principi. Leggi questo articolo sul blog di Jeff Atwood:

Legge di Curly: fai una cosa

Prestare attenzione ai tre principi fondamentali del moderno sviluppo del software, ovvero:

Sebbene personalmente non consiglieresti quanto segue , ti mostrerò un esempio per motivi di semplicità se desideri semplicemente racchiudere le cose:

function my_method(variable){
/*
 * 75% of method here
 */
if (variable == 0){
    /* variation one here */
}
else{
    /* variation two here */
}
return value;
}
    
risposta data 27.02.2015 - 07:07
fonte
2

Un modo comune di rifattorizzare il codice in questo modo è attraverso l'ereditarietà, utilizzando metodi astratti o virtuali per il comportamento che può variare.

Supponiamo che tu abbia un metodo per pagare i dipendenti e un altro per pagare il CEO:

void PayNormalEmployee()
{
    // do stuff
    // do more stuff
    // give meager bonus
    // do final stuff
}

void PayCeo()
{
    // do stuff
    // do more stuff
    // give huge bonus
    // do final stuff
}

Supponiamo che tu debba fare le cose nell'ordine sopra; non puoi semplicemente riordinare per impostare la parte bonus come ultimo passo.

Il modo di refactoring è attraverso l'ereditarietà. Metti il comportamento comune in una classe base e metti il comportamento distinto in sottoclassi distinte. La tua linea comune (o set di linee) dovrebbe chiamare un metodo separato. Ad esempio:

abstract class EmployeeBase
{
    public void Pay()
    {
        // do stuff
        // do more stuff
        PayBonus();
        // do final stuff
    }

    protected abstract void PayBonus();
}

class NormalEmployee : EmployeeBase
{
    override void PayBonus()
    {
        // pay meager bonus
    }
}

class Ceo : EmployeeBase
{
    override void PayBonus()
    {
        // pay huge bonus
    }
}

Se il tuo dipendente è un dipendente normale o un amministratore delegato, lui / lei ha accesso al metodo Pay, ma verrà utilizzata l'implementazione nella classe derivata.

Se esiste un'implementazione "predefinita", puoi semplificare la procedura:

class Employee
{
    public void Pay()
    {
        // do stuff
        // do more stuff
        PayBonus();
        // do final stuff
    }

    protected virtual void PayBonus()
    {
        // pay meager bonus
    }
}

class Ceo : Employee
{
    override void PayBonus()
    {
        // pay huge bonus
    }
}

Ancora una volta, l'amministratore delegato ha accesso al metodo Pay, ma utilizzerà la sua speciale implementazione PayBonus; ma tutto continuerà comunque nell'ordine corretto.

    
risposta data 27.02.2015 - 16:19
fonte