È una cattiva pratica incapsulare una singola operazione in una classe? [duplicare]

2

Recentemente ho avuto un backstage su StackOverflow sulla mia risposta a questa domanda .

La domanda era semplice. L'autore voleva trasformare un numero in una versione abbreviata che aggiungeva K , M o B a seconda della dimensione del numero.

Un utente ha suggerito una risposta molto semplice e ingenua:

function round_thousands($number){
    if($number < 1000){
        return $number;
    } else {
        return number_format($number/1000, 1).'K';
    }
}

Ignorando il fatto che il nome della funzione non corrisponde a quello che fa e che converte solo in K , posso capire perché questa risposta potrebbe essere allettante all'inizio.

Tuttavia, ho scelto di adottare un approccio più solido e creare un'interfaccia:

interface Quantifier {
    public function quantify($value);
}

Ho quindi creato un quantificatore predefinito chiamato NumberQuantifier:

class NumberQuantifier implements Quantifier {
    protected $quantifierList;

    public function __construct($quantifierList) {
        $this->quantifierList = $quantifierList;
        arsort($this->quantifierList); //Make sure they are largest too smallest.
    }

    public function quantify($number) {
        foreach ($this->quantifierList as $symbol => $threshold) {
            if ($threshold > $number) continue;

            return number_format($number / $threshold, 1) . $symbol;
        }
    }
}

Cose semplici, pensavo.

Questo ti permette di creare quantificatori per tutti i tipi di cose: dimensione del file, massa, lunghezza, volume, ecc. Senza dover copiare / incollare una nuova funzione ogni volta:

$numberQuantifier = new NumberQuantifier(array(
    'B' => 1000000000,
    'M' => 1000000,
    'K' => 1000
));

Inoltre, nel caso in cui avessi un caso più avanzato, potresti implementare Quantifier e creare alcune funzionalità personalizzate per quantificare.

Tuttavia, sono stato presto incontrato da un critico che ha insistito sul fatto che non dovrei usare una lezione per questo. In effetti, era irremovibile, nonostante i miei numerosi tentativi di soddisfare perché una classe sarebbe stata l'ideale.

Argomento

Il suo argomento era che una classe

  • deve avere uno stato mutevole
  • deve incapsulare più di una singola operazione

Altrimenti, sostiene, dovrebbe essere una funzione globale.

La sua alternativa (credo) sarebbe di fare qualcosa del tipo:

function number_quantify($value, $quanitfierList) {
    foreach ($quantifierList as $symbol => $threshold) {
        if ($threshold > $number) continue;

        return number_format($number / $threshold, 1) . $symbol;
    }
}

function quantify_mass($value) {
    $quantifieryList = array(); //quantifiers here.

    return number_quantify($value, $quantifierList);
}

function quantify_length($value) { //.. }

//etc.

In sostanza, per qualsiasi tipo di quantificatore, devi creare una nuova funzione che possa sempre vivere nello spazio globale. In alternativa, puoi passare manualmente $quantifierList a ogni chiamata di funzione di number_quantify che sembra un incubo di manutenzione.

Credo che il mio uso di un'interfaccia e del polimorfismo non solo renda il codice più pulito e più gestibile, ma faciliterebbe anche un migliore test dell'unità.

Domanda

Mi sbaglio? Avere una classe che incapsula una singola operazione e nessuno stato mutabile qualche tipo di odore di codice?

    
posta crush 05.02.2014 - 16:15
fonte

1 risposta

3

No, non sei sbagliato, a condizione che tu stia lavorando con una lingua in cui è richiesta una classe per la sostituzione downstream.

In (versioni precedenti di) C #, potresti in qualche modo perfezionare una funzione statica, ma è più utile sostituirla a quella della semplice sottoclasse di una classe semplice, specialmente se usi uno schema di fabbrica.

In JavaScript, tuttavia, è più facile sostituire una funzione che definire un nuovo prototipo, quindi il sovraccarico di un'interfaccia e di una classe dichiarate è solo una perdita di memoria senza vantaggi.

E anche in JavaScript, ci sono dei motivi per creare una classe prototipo con un solo metodo. Non ultimo, se questo metodo "semplice" può essere sostituito con un insieme di funzioni molto complicato anziché con poche righe.

    
risposta data 05.02.2014 - 16:44
fonte

Leggi altre domande sui tag