Alcuni anni fa ho progettato una classe che aveva due proprietà. Le due classi ChildA e ChildB avevano un protocollo ricco con molte proprietà e metodi, ma erano solo lontanamente correlate nel mio modello. Entrambi discendono da una classe DatabaseEntity, che memorizza un ID GUID. Tuttavia, ci sono diverse classi di base intermedie nella gerarchia e questa relazione è piuttosto banale. Molte mie classi discendono da DatabaseEntity. Nel tempo sono state aggiunte altre due classi a questo modello, quindi oggi abbiamo qualcosa di simile a questo:
public class Parent
{
public ChildA TheChildA { get; set;}
public ChildB TheChildB { get; set;}
public ChildC TheChildC { get; set;}
public ChildD TheChildD { get; set;}
}
Le proprietà si escludono a vicenda: un'istanza di Parent deve avere SOLO di TheChildA, TheChildB, TheChildC o TheChildD; altrimenti questi sono impostati su null. Le proprietà sono supportate da campi privati e quando vengono impostate su un oggetto, le altre sono impostate su null.
La mia domanda è questa: è meglio calarsi come è, magari aggiungendo un'altra classe a questo modello ogni 2 anni, o refactoring e sostituire la proprietà con una singola interfaccia come questa:
public class Parent
{
public IChild TheChild { get; set; }
}
Posso quindi rendere ciascuno di ChildA, ChildB ecc implementare questa interfaccia. Non sarebbe un'interfaccia marcatore; l'interfaccia avrebbe forse solo due membri, e quei membri non sarebbero così importanti. Al contrario, le classi Genitore e figlio hanno un centinaio di membri.
Il mio schema originale rappresenta un particolare tipo di "odore di codice"? E il mio refactoring proposto è conforme o rappresenta un particolare modello di progettazione o una pratica software raccomandata? Mi sembra che avere due proprietà reciprocamente esclusive possa essere accettabile, ma avendo diversi mezzi il codice è piuttosto disordinato.