Un genitore con figli deve avere un figlio predefinito o un figlio deve avere una proprietà di default?

1

Quale dei seguenti due modelli ha più senso? Mi sto appoggiando al primo perché può esserci solo un figlio predefinito.

Gli esempi sono in C # ma penso che possa essere applicato anche ad altre lingue.

Qui DefaultChild contiene uno degli elementi in Children .

class Parent
{
    int ID { get; set; }

    Child DefaultChild { get; set; }

    IEnumerable<Child> Children { get; set; }
}

class Child
{
    int ID { get; set; }
}

Qui uno degli elementi in Children ha Default impostato su true mentre gli altri hanno impostato su false .

class Parent
{
    int ID { get; set; }

    IEnumerable<Child> Children { get; set; }
}

class Child
{
    int ID { get; set; }

    bool Default { get; set; }
}

Una situazione concreta: un User nel nostro sistema ha uno o più Customer s allegati. Al momento dell'accesso, se detto User ha un Customer predefinito, funzionano immediatamente con questo Customer . Se non lo fanno, devono selezionare un Customer per lavorare sotto. Durante l'accesso, possono passare da Customer s.

    
posta Stijn 02.06.2014 - 16:42
fonte

2 risposte

6

Nel tuo scenario specifico, un genitore dovrebbe avere un DefaultChild. Il problema con il dare a un figlio una proprietà IsDefault è che A) consente Genitori con più figli predefiniti e B) non consente ai genitori dello stesso figlio di avere impostazioni diverse per il loro bambino. Il fatto che nessuno di questi scenari possa realmente accadere è irrilevante; entrambi gli scenari logicamente hanno senso, nonostante non corrispondano affatto alle tue intenzioni.

Da una prospettiva di alto livello, ha più senso parlare del figlio predefinito di un genitore piuttosto che dire che un particolare bambino è intrinsecamente un default.

    
risposta data 02.06.2014 - 17:16
fonte
3

Stai confondendo i dettagli del contratto con i dettagli di implementazione. Un contratto è l'API che gli oggetti espongono per essere manipolati.

Quello su cui devi decidere è quale interfaccia hai bisogno per quegli oggetti. Il modo in cui tali oggetti sono implementati è solo un esercizio di efficienza del codice.

Supponiamo che le seguenti interfacce abbiano un senso.

public interface iNode
{
     int getID();
     bool isDefault();
}

public interface iParent : iNode
{
     iNode getDefault();
     IEnumerable<iNode> getChildren();
}

Quali metodi ha la tua interfaccia può limitare o espandere i dettagli di implementazione. Devi decidere se hai bisogno della conoscenza di isDefault di una iNode nel tuo codice altrove.

Ecco un approccio.

public class Node : iNode
{
    public int getID() { return _id; }
    public bool isDefault() { return _default; }
}

public class Parent : Node
{
    public iNode getDefault() { return getChildren().FirstOrDefault(child=>child.isDefault()); }
    public IEnumerable<iNode> getChildren() { return _children; }
}

In alternativa, se non desideri che iNode esponga che è un valore predefinito.

public class Node : iNode
{
    public int getID() { return _id; }
}

public class Parent : Node
{
    public iNode getDefault() { return _default; }
    public IEnumerable<iNode> getChildren() { return _children; }
}

È importante concentrarsi su come verranno utilizzati i tuoi oggetti e non essere eccessivamente distratto da come verranno implementati. Ti aspetti di avere riferimenti a iNode oggetti e non hai più un riferimento al suo genitore? Se è così, forse dovrebbe avere un flag che è l'impostazione predefinita.

Tuttavia, puoi semplicemente aggiungere getParent all'interfaccia iNode .

Penso che devi prima svuotare i tuoi contratti di oggetti.

    
risposta data 02.06.2014 - 17:17
fonte

Leggi altre domande sui tag