Condivisione del codice costruttore tra classi che non ereditano l'una dall'altra

4

Esiste una libreria PHP di classi (generate da un WSDL) che non possono essere modificate. Questi sembrano il sotto per semplicità.

class System extends \SoapClient
{
    public function __construct(array $options = array(), $wsdl = 'http://example.com/system?wsdl')
    {
       // Do configuration and include required classes.

       parent::__construct($wsdl, $options);
    }
}

class Report extends \SoapClient
{
    public function __construct(array $options = array(), $wsdl = 'http://example.com/report?wsdl')
    {
       // Do configuration and include required classes.

       parent::__construct($wsdl, $options);
    }
}

Il codice personalizzato deve eseguire alcune configurazioni (ad esempio l'impostazione di alcune intestazioni SOAP e la versione SOAP) ogni volta che è richiesto un oggetto System o Report. L'implementazione attuale è la seguente.

class mySystem extends System
{
  public function __construct($wsdl, $configuration) {

    $options = array(
      'soap_version' => SOAP_1_2,
    );

    // Do more stuff here.

    parent::__construct($options, $wsdl);
  }
}

class myReport extends mySystem
{
  public function __construct($wsdl, $configuration) {
    parent::__construct($options, $wsdl);
  }
}

Quanto sopra funziona, ma il mio IDE mi sta urlando ogni volta che faccio qualcosa su myReport (non riesco a trovare il metodo, ecc.) e penso che funzioni solo perché a PHP non interessa molto il tipo e tutti i metodi attuali vengono passati al metodo SoapClient->__doRequest() . Qualsiasi pensiero eccessivo, più concreto, sul perché questo sia male, è il benvenuto.

Voglio refactoring questo per un design migliore. La prima cosa è che mySystem estende correttamente System ma myReport dovrebbe estendere anche Report . Ciò significa che il codice costruttore deve essere duplicato in mySystem e myReport . C'è un modo per aggirare questo?

I miei pensieri finora:

  • Hanno una caratteristica di "setup" che sia mySystem che myReport usano e chiamano il metodo appropriato "setup" nei loro costruttori. Il blocco principale qui è la versione di PHP su alcuni sistemi è 5.3 sebbene ci siano piani per aggiornarli.
  • Avere un metodo factory in grado di istanziare le classi richieste. Non sicuro al 100% di come sarebbe questo.
posta Malks 03.12.2014 - 16:40
fonte

1 risposta

2

Personalmente userò i metodi factory per creare ciascuno di questi oggetti e dimenticherò l'ereditarietà aggiuntiva che hai progettato.

La forma di questa sarebbe una classe ReportFactory e una classe SystemFactory che avrebbe i propri metodi di creazione. Nei metodi di creazione si istanzia la classe richiesta e quindi si esegue l'inizializzazione specifica dell'oggetto all'interno del metodo factory.

Laddove esiste una corrispondenza nei requisiti di configurazione (molto probabilmente a livello SOAP), allora quel lavoro può essere portato a una classe comune per gestire quella parte della configurazione.

Sembrerebbe che il livello aggiuntivo di eredità che hai aggiunto non fornisca alcun valore reale, e non c'è distinzione tra il valore ereditato e la classe base, a parte la semantica dell'inizializzazione diversa. Pertanto ritengo che tale approccio dovrebbe essere giustificato più di quanto non lo sia attualmente se si dovesse continuare su questa strada.

    
risposta data 21.01.2015 - 00:27
fonte

Leggi altre domande sui tag