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?