Convenzione Java - Implementazione di due funzioni simili per due oggetti diversi

0

Ho due classi, chiamiamole Foo e Bar . Entrambi estendono classi diverse ( Foo extends X , Bar extends Y ), che hanno un antenato comune "via via" l'albero di ereditarietà, qualcosa del genere:

Sia Foo che Bar hanno alcuni membri di classi comuni (e alcuni membri che non condividono) e vorrei implementare un metodo che sia lo stesso per entrambe le classi, agendo su questi membri . Il problema è - Non riesco a cambiare l'albero di ereditarietà e aggiungere una superclasse che sarà la stessa per entrambi (mentre questo potrebbe essere un segno per una cattiva progettazione delle classi e dell'ereditarietà, questo non è quello che chiedo qui).

Per semplicità, supponiamo che i membri simili della classe saranno member1 e member2 , e il nome della funzione rilevante sarà func() .

Un'opzione che ho pensato è di incapsulare i membri della classe simili in una nuova classe e creare il relativo metodo per essa. Ad esempio, posso creare una classe denominata Baz che conterrà sia member1 che member2 e Foo e Bar conterranno la classe Baz anziché questi membri. I metodi func() in Foo e Bar chiameranno solo baz.func() .

Questa è davvero una soluzione. Tuttavia, quale dovrebbe essere una soluzione in cui non posso cambiare anche i membri della classe? In tal caso, ho pensato di implementare sia Foo che Bar per implementare un'interfaccia (per semplicità chiamiamola IFunc ). E crea un metodo (o static o no) da qualche altra parte che avrà un argomento IFunc che imiterà func . Ma questa sembra una soluzione non così buona. Quale sarà la soluzione migliore per questo caso?

Per chiarire: sto cercando di eliminare la duplicazione del codice nell'implementazione di func

Grazie!

    
posta Mickey 13.12.2018 - 10:55
fonte

1 risposta

2

Ok, presumo qui che non puoi in effetti modificare le super classi di Foo o Bar nella mia risposta.

Logicamente, Foo e Bar derivano dalle rispettive classi X e Y per un motivo. Foo è un tipo di X e non un tipo di Y e viceversa. Rispettalo e non provare a forzare Foo e Bar in una strana classe ibrida derivante da un antenato remoto. Se la relazione tra Foo e Bar non rispecchia l'ereditarietà come è, quindi crea un nuovo albero di ereditarietà che lo fa.

In situazioni come questa, in genere utilizzi un modello Adattatore . L'idea è di creare una nuova classe astratta che rappresenti questa nuova relazione che rappresenta queste cose in comune. Quindi le tue classi concrete estendono questa classe astratta che fa poco più dell'incapsulamento di Foo o Bar e fornisce un comportamento coerente tra i due.

Quando hai bisogno di usarlo, devi solo gestire la classe astratta che unifica il comportamento tra i due. Ovviamente, il lato negativo è che non si può usare questo adattatore dove normalmente si può usare Foo o Bar , ma se ho capito bene, nessuno dei due può essere usato in modo intercambiabile come lo è comunque. Otterrai tutta la flessibilità di cui hai bisogno senza la goffaggine di provare a far entrare una sfera in un buco quadrato.

Spero che ti aiuti!

    
risposta data 13.12.2018 - 12:18
fonte