Utilizzo dei tratti PHP per simulare l'ereditarietà multipla

4

Per questa domanda voglio presentare il mio attuale design e la mia idea di usare un tratto. Vorrei sapere se la mia comprensione dei tratti è corretta e se il mio problema può essere risolto con un altro design che non li coinvolge.

La mia attuale gerarchia di classi nel mio framework è simile a questa:

interface IPage { /* ... */ }
interface IForm extends IPage { /* ... */ }
abstract class AbstractPage implements IPage { /* ... */ }
abstract class AbstractForm extends AbstractPage implements IForm { /* ... */ }

Nelle mie applicazioni basate sul framework ho usato il seguente:

abstract class AbstractBasePage extends AbstractPage { /* ... */ }

Così potrei aggiungere altro materiale a tutte le pagine per questa particolare applicazione che non è comune al framework o ad altre applicazioni. Questo ha funzionato bene fino a quando ho implementato la separazione in pagine e moduli come indicato nel primo frammento. Ora ho finito con qualcosa di simile:

abstract class AbstractBasePage extends AbstractPage { /* ... */ }
abstract class AbstractBaseForm extends AbstractForm { /* ... */ }

Supponiamo che in una applicazione ci debba essere una variabile per ogni pagina e modulo che indica se qualcosa di speciale viene visualizzato nei modelli. Avrei bisogno di introdurre la stessa variabile in AbstractBasePage e in AbstractBaseForm . Ciò mi costringerebbe a mantenere sincronizzati entrambi i frammenti, il che non è affatto positivo.

Stavo pensando di creare un tratto che espone variabili e funzioni a entrambe le classi, a cui possono a loro volta fare riferimento nelle funzioni corrispondenti. L'utilizzo di un tale tratto ridurrebbe la duplicazione del codice almeno dal momento che potrei introdurre un metodo pubblicamente accessibile che viene chiamato da entrambe le classi, ma a parte questo c'è un'astrazione decente, non è vero?

È questo che dovrebbero essere d'aiuto i tratti? C'è un approccio più adatto o in questo caso i tratti sono in realtà il design suggerito?

    
posta Christian Ivicevic 18.12.2016 - 14:50
fonte

2 risposte

0

In questo caso particolare ho finito per introdurre un'interfaccia (con funzioni utilizzate dal framework) come un contratto che viene esteso da IPage . Inoltre ho avuto l'implementazione particolare che è identica per pagine e form in un tratto che poi a sua volta è stato utilizzato nelle classi framework AbstractPage e AbstractForm .

L'implementazione menzionata era all'interno del framework stesso per avere un design conciso che poi a sua volta è usato per farlo anche nelle mie applicazioni. Per le applicazioni ho introdotto un tratto che contiene le variabili e le funzioni identiche in entrambe le pagine e le forme, che poi vengono utilizzate nelle classi AbstractBasePage e AbstractBaseForm .

Per questo scenario avevo bisogno di una funzionalità di copia e incolla essenzialmente supportata dal linguaggio, poiché volevo aggiungere qualcosa che non fosse facilmente utilizzabile con l'ereditarietà, ma qualcosa che può essere introdotto in classi che fanno parte di gerarchie di classi diverse . Quindi ho deciso di usare i tratti.

    
risposta data 26.12.2016 - 22:19
fonte
0

Nella tua risposta non ci sono abbastanza dettagli per suggerire qualcosa di concreto, ma penso che la tua gerarchia di classi vada contro ISP . Non penso che ci sia bisogno di grandi classi astratte.

Pensa a creare interfacce specializzate per ogni scopo, seguendo SRP . E poi usa i tratti per mettere il comportamento in classi (non consigliato se non sappiamo di più sul tuo progetto) o preferisci la composizione all'ereditarietà per fare lo stesso.

La composizione può essere usata in molti modi, penso. Ma ciò che mi viene in mente è creare serie di due interfacce per un compito specifico. Uno per una classe contenente con un singolo metodo e un altro per una classe, implementando tale comportamento:

  interface ISpecificActionProvider {
    /**
      * @return ISpecificActionHandler
      */
    public function getSpecificActionHandler();
  }

Questo consiglio potrebbe essere buono o addirittura pessimo, a seconda delle esigenze del tuo progetto. È fornito solo per dare un'idea.

    
risposta data 19.12.2016 - 12:05
fonte

Leggi altre domande sui tag