Come chiarire che un metodo può essere ignorato?

7

Ho una libreria che uso in diverse applicazioni. Ha un metodo che restituisce un URL:

class UrlBuilder {
  public function url($config) {
    $config = do_some_checks($config);
    return make_url($config));
  }
}

Spesso un'applicazione vuole alterare il modo in cui viene creato l'URL e vorrei chiarire il modo in cui la libreria è implementata. Ho trovato queste soluzioni:

  1. Menzionalo nei documenti della biblioteca, ma altrimenti lascia che l'applicazione esegua l'override del metodo come qualsiasi altro:

    class MyAppUrlBuilder extends UrlBuilder {
      public function url($config) {
        $config = do_some_checks($config);
        return make_url_differently($config);
      }
    }
    
  2. Chiama una funzione separata che è solo lì per essere sovrascritta:

    class UrlBuilder {
      public function url($config) {
        $config = do_some_checks($config);
        $config = $this->alterConfig($config);
        return make_url($config));
      }
    
      protected function alterConfig($config) { return $config; }
    }
    
  3. Fornisci un setter per impostare un callback di personalizzazione:

    class UrlBuilder {
      public function url($config) {
        $config = do_some_checks($config);
        if ($this->configModifier)
          $config = $this->configModifier($config);
        return make_url($config));
      }
    
      public function setConfigModifier($configModifier) {
        $this->configModifier = $configModifier;
      }
    }
    

C'è una differenza semantica e (se non è una questione di gusti) è preferibile uno di questi?

    
posta AndreKR 28.04.2016 - 05:32
fonte

1 risposta

9

Preferirei l'opzione n. 4: evita di fare affidamento sull'eredità.

Crea solo UrlBuilder di un'interfaccia e dai alle persone la possibilità di iniettare la loro implementazione nel processo, ignorando il valore predefinito che hai fornito.

interface UrlBuilder {
    public function url($config);
}

class DefaultUrlBuilder implements UrlBuilder{
  public function url($config) {
    $config = do_some_checks($config);
    return make_url($config));
  }
}

In questo modo si sposta la responsabilità: non è bisogno di preoccuparsi troppo di tutti i possibili modi in cui potrebbero voler sottoclasse la propria implementazione, perché non hanno a. Se i loro bisogni sono semplici e la sottoclassi, beh, bene per loro, hanno trovato una scorciatoia. Se i loro bisogni sono complessi, beh, hanno la libertà di fare qualcos'altro.

... Detto questo, tra le tre opzioni, il mio preferito è il n. 2, se hai una visione molto chiara di ciò che vorrebbero personalizzare.

    
risposta data 28.04.2016 - 07:19
fonte

Leggi altre domande sui tag