Come faccio a gestire i membri ereditati non necessari?

3

Considera il seguente diagramma UML:

In poche parole:

  • ChildClass1 e ChildClass2 utilizzano tutti i membri di ParentClass .
  • ChildClass3 utilizza solo Member1 e Member2 e il valore di Member5 è un valore costante. (0)

Quale sarebbe il modo migliore per implementare questo comportamento?

Al momento, ho ereditato la classe come normale e sovrascritto Member3 e Member4 per lanciare NotSupportedException e reso Member5 sola lettura e restituito 0 per tutto il tempo.

Non sono convinto che questa sia l'idea migliore in quanto Member3 e Member4 sono irrilevanti a ChildClass3 .

Altre cose che ho considerato:

  • Invece di ereditare. Creare un ParentClass all'interno di ChildClass3 e quindi esporre solo le proprietà di cui ho bisogno.

  • Usare le interfacce, ma è diventato troppo complicato, troppo veloce.

  • Ristrutturazione della gerarchia, ma non l'ho guardato troppo nei dettagli.

Ci sono altre opzioni?

Per contesto: Ho cercato di mantenere questo semplice per evitare muri di codice, ma questo sembra aver portato alla confusione. Spiacenti = /

ParentClass in questo caso è Person, con i seguenti campi:

  • Nome: stringa
  • Cognome: stringa
  • Sesso: stringa
  • DateOfBirth: Nullable < DateTime >
  • Posizione: int

Ora nella maggior parte dei casi, le classi figlie (Impiegato, Manager, ecc.) usano tutti questi campi. Comunque una classe (Visitatore), ho solo bisogno di sapere un nome, non mi interessa la loro età o posizione. La posizione in questo caso è impostata su 0. So che è un numero magico, ma è importante per il sistema.

Posso capire come questo viola l'LSP, ma allo stesso tempo, non penso davvero che avere interfacce per dividere un nome e altre informazioni personali abbia molto senso. Dare un nome a questo mi darebbe anche un mal di testa.

Nelle altre classi, ci sono interfacce ovunque; IMedicalData, IContactInformation, ecc.

Ho scelto l'ereditarietà solo in questo caso poiché un visitatore è tecnicamente un tipo di persona.

    
posta Jake 13.04.2016 - 12:12
fonte

2 risposte

7

Di solito dovresti farlo in questo modo:

Questo è il modo più canonico per risolvere il tuo problema. In generale tu aggiungi comportamenti e stati quando sottoclassi

    
risposta data 13.04.2016 - 15:25
fonte
5

At the moment, I've inherited the class as normal and overridden Member3 and Member4 to throw NotSupportedException and made Member5 read-only and return 0 all the time.

I'm not convinced this is the best idea as Member3 and Member4 are irrelevant to ChildClass3.

Non è la migliore idea: questo è un classico esempio di violazione del Principio di sostituzione di Liskov .

La semplice risposta al modo migliore per implementarla è "non usare l'ereditarietà, usa le interfacce e la composizione come richiesto".

La risposta più dettagliata deve fare qualche ipotesi su cosa sia Member[1-5] , ma qualcosa del tipo:

public interface IMember12And5
{
    Member1;
    Member2;
    Member5;
}

public interface IAllMembers : IMember12And5
{
    Member3;
    Member4;
}

public class ChildClass1 : IAllMembers  { ... }

public class ChildClass2 : IAllMembers  { ... }

public class ChildClass3 : IMember12And5 { ... }

potrebbe funzionare. In alternativa, componi ChildClass[1-2] da Member12And5 e Member3And4 e hai ChildClass3 composto solo da Member12And5 .

Senza ulteriori dettagli su cosa siano realmente i membri, non è possibile offrire una risposta migliore.

    
risposta data 13.04.2016 - 12:28
fonte

Leggi altre domande sui tag