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?