Rifiutare la dichiarazione di commutazione di codice errato senza distorcere tutto

0

Di tanto in tanto inciampo su dichiarazioni di switch durante a Sessione di revisione del codice.

Mi piacerebbe trovare un modo più elegante di questo codice

....

$istannceOfClass = $repository->loadFoo(); 
switch($istannceOfClass) 
{  
    case $istannceOfClass instanceOf derivedClassAB:
        $istannceOfClass->callA(); 
        $istannceOfClass->callB(); 
        break;
    case $istannceOfClass instanceOf derivedClassCD:
        $istannceOfClass->callC(); 
        $istannceOfClass->callD(); 
        break;
    case $istannceOfClass instanceOf derivedClassEF:
        $istannceOfClass->callE(); 
        $istannceOfClass->callF(); 
        break;
}

Ho pensato di migliorare il codice. potrebbe essere usata la classe anonima? Non riesco a modificare la gerarchia e le sottoclassi di $ istannceOfClass e $ istannceOfClass stesso.

un tentativo: migliorare, correggere, lanciare Ho usato anonymouse per comodità. Codice che non può essere modificato

interface baseclass { }

class ab implements baseclass 
{
    public function callA()
    {
        return "<br>class ab Call A";

    } 

    public function callB()
    {
        return "<br>class ab Call B";
    } 
}

class cd implements baseclass 
{
    public function callC()
    {
        return "<br>class cd Call B";

    } 

    public function callD()
    {
        return "<br>class cd Call C";
    } 
}

Nuovo codice per refactoring prima interfaccia comune con tutti i metodi

interface commonABCDEF 
{
    public function callA(); 
    public function callB();
    public function callC(); 
    public function callD();
    public function callE(); 
}

seconda classe astratta per comportamento predefinito

class abstractCommonAbcdef implements commonABCDEF
{    
    //common behavior
    public function callA() { return '<br>default A'; }
    public function callB() { return '<br>default B'; }
    public function callC() { return '<br>default C'; }
    public function callD() { return '<br>default D'; }
    public function callE() { return '<br>default E'; }
    //abstract public function run(); 

}

adattatore per il caso 1 dell'interruttore

$abOverride = new class(new ab()) extends abstractCommonAbcdef 
{   
    public function __construct(baseclass $abcde)
    {
        $this->abcde = $abcde;
    }     

    public function callA() 
    {
        return $this->abcde->callA(); 
    }

    public function callB() 
    {
    return $this->abcde->callB(); 
    }

    public function run()
    {

    } 
};

....

final call al method

$rightClass = new class($abOverride)
{
    public function __construct(abstractCommonAbcdef $abcommonABCDEF) 
    {
        $this->abcommonABCDEF = $abcommonABCDEF; 
    }

    public function getBo() {
        return $this->abcommonABCDEF;
    }
};


echo $rightClass->getBo()->callA(); 
echo $rightClass->getBo()->callB(); 
echo $rightClass->getBo()->callC(); 
echo $rightClass->getBo()->callD();
    
posta BruceStackOverFlow 20.05.2018 - 14:54
fonte

1 risposta

9

Puoi creare una nuova interfaccia e far sì che tutte e tre le classi la implementino.

Ognuno implementerà lo stesso metodo ma con un'implementazione diversa.

L'istruzione switch può quindi essere sostituita con una chiamata a tale metodo.

Martin Fowler chiama questo refactoring Sostituisci condizionale con polimorfismo . Nel suo esempio introduce una superclasse astratta piuttosto che un'interfaccia. Potrebbe funzionare in entrambi i modi, ma io tendo a preferire le interfacce.

    
risposta data 20.05.2018 - 14:57
fonte