Come faccio a rifattorizzare un servizio grafico su dove posso incapsulare le dichiarazioni if / then / else?

2

Dispongo di un servizio grafico in cui utilizzo le istruzioni if / then / else.

class GraphService
{
    function getGraphData(array $products)
    {
        foreach ($products as $products)
        {
            $gotPumpGraph = false;
            $model = $product['model'];
            $item = $product['model'];


            if ($model == "a" || $model == "b")
            {
                $graph = new APump();
                $graph->getGraphData($itemId);

                $graphData = $graph;
                $gotPumpGraph = true;
            }

            if ($model == "c" || $model == "d")
            {
                $graph = new CPump(new SomeDifferentDependency());
                $graph->getSomeOtherData($itemId);

                $graphData = $graph;
                $gotPumpGraph = true;
            }

            if ($gotPumpGraph)
            {
                 //put graphs into common structure
                 $graphs[] = array(
                     'itemId' => $itemId,
                     'graphData' => $graphData
                 );
            } 
        }      
    }
}

Ciò che sta facendo il servizio è il consolidamento di vari formati di grafici in uno solo. Quindi ogni blocco if ha diverse dipendenze e strutture, che sono tutte consolidate in una struttura standardizzata.

L'obiettivo della mia domanda è trovare un insieme adatto di schemi di progettazione, in cui nascondere le diverse dipendenze presenti in ogni blocco if .... Come?

Il mio primo pensiero è di usare una fabbrica ma ... non vedo un percorso chiaro a questo. Il codice all'interno di if blocchi è un codice legacy diverso che è diverso per i diversi blocchi e i grafici sono disponibili in diversi formati. Ho pulito un po 'il codice per la domanda, ma ho lasciato diversi metodi / dipendenze nei blocchi if .

    
posta Dennis 07.08.2018 - 21:14
fonte

1 risposta

4

Penso che tu abbia ragione e suggerirei un modello di fabbrica per costruire le tue diverse "pompe". Ogni pompa dovrebbe avere lo stesso metodo: getData , che è ciò che la tua classe principale dovrebbe chiamare:

foreach ($products as $product)
{
    $graph = PumpFactory::forModel($product['model'];

    $graphs[] = [
        'itemId' => $product['itemId'],
        'graphData' => $graph->getData($product['model']),
    ];
}

Il metodo getData per ogni tipo di pompa chiamerà ovviamente il metodo corretto sottostante ( getGraphData o getSomeOtherData ). getData sarebbe il metodo che esisterebbe su PumpInterface per creare il contratto a cui GraphService e altri oggetti possono dipendere, con i dettagli di come ogni diverso tipo di pompa ottiene i dati delegati ai singoli tipi.

I dettagli dello stabilimento dipendono dai tuoi limiti effettivi, ma solo per mostrare come potrebbe essere fatto con il codice presentato nella domanda:

class PumpFactory
{
    public static function forModel($model)
    {
        switch($model) {
            case 'a': /* FALL THROUGH */
            case 'b':
                return new APump();
            case 'c': /* FALL THROUGH */
            case 'd':
                return new CPump(new SomeDifferentDependency());
            default:
                throw new InvalidArgumentException('Invalid model: ' . $model);
        }
    }
}

La mia preferenza personale è di lanciare un'eccezione nel caso predefinito, nel qual caso dovresti gestire quell'eccezione a un certo punto. Un'opzione diversa è quella di restituire null e testarlo prima di chiamare getData nel tuo ciclo.

    
risposta data 07.08.2018 - 22:03
fonte

Leggi altre domande sui tag