Possono due oggetti avere più tipi di relazioni?

3

Supponiamo di avere una relazione molti a molti nel database come questa:

CREATE TABLE Person (ID int, name varchar(100), dateofbirth datetime, Gender char(1), primary key (ID))
CREATE TABLE Sport (ID int, description varchar(30), primary key (ID))
CREATE TABLE PersonCanPlaySport (Person ID int references Person(ID), SportID int references Sport(ID), PRIMARY KEY (SportID, PersonID))

Le tabelle mostrano a quale sport può partecipare una persona. Ora guarda la classe qui sotto:

public class Person
{
   public List<Sport> Sports;
   public int FitnessLevel;
   public datetime DateOfBirth;
   public string Gender; //M or F

   public Person()
   {
     Sports = new List<Sport>();
   }

   //allSports contains all the sports from the database i.e. allSports contains about 100 sports.  AddSports determines what sports (out of the 100) that the user can participate in based on: Gender, age, Fitness Level etc
   public void AddSports(List<Sports> allSports)
   {
      Sports.Clear();
      ((List<Sport>)Sports).AddRange(allSports
      .Where(sport => sport.CanPlay(this)));
   }

}

Sembra esserci una relazione di associazione e una relazione di composizione tra persona e sport. Ecco perché:

1) La persona crea un'istanza di un elenco di sport nel costruttore, quindi controlla il ciclo di vita degli sport 2) La persona usa una lista di sport in AddSports, che credo lo renda associazione

È un odore di codice? Che tipo di relazione esiste tra i due oggetti? Come sarebbe rappresentato su un Object Diagram?

Aggiorna

In seguito alla risposta e ai commenti utili di @Neil; Credo che stia suggerendo di fare questo:

//Application Service Layer
List<Sport> sports = Repository.GetAllOffers();
foreach sport As Sport in sports
{
   person.AddSports(sport);
}

//Domain class
public class Person
{
   public List<Sport> Sports;
   public int FitnessLevel;
   public datetime DateOfBirth;
   public string Gender; //M or F

   public Person()
   {
     Sports = new List<Sport>();
   }

   public void AddSport(Sport sport)
   {
      if(sport.CanPlay(this))
      {
         Sports.Add(sport);
      }
   }

}

Non sono sicuro che mi piaccia l'idea che il livello del servizio di applicazione debba scorrere su Sport.

    
posta w0051977 21.11.2017 - 10:15
fonte

1 risposta

3

La relazione del database tra Person e Sport come ho capito è molti-a-molti, con una tabella intermedia PersonCanPlaySport che collega i due. Ciò significa che un Person può essere associato a molti Sports e un Sport può essere associato a molti Persons .

Ora che comprendiamo la relazione del database, la relazione utilizzata nel codice non dovrebbe essere diversa. Potenzialmente un'istanza Person avrebbe una lista di Sport e un'istanza Sport avrebbe una lista di Person .

Penso quindi che sarebbe scorretto mettere la logica della presenza o meno di Person di uno specifico Sport direttamente all'interno di Person o viceversa. Considera l'uso di un oggetto PersonSportDao che ha dato un Person , può restituire tutto Sports e dato un Sport può restituire tutto Persons . Il chiamante su AddSports renderebbe la chiamata a PersonSportDao , o meglio ancora, Person istanza stessa carica il Sports quando richiesto, chiamando PersonSportDao con this .

Se desideri verificare i dettagli relativi a età o sesso, potresti creare un'altra classe PersonSportManager . In altre parole, Person non è proprietario di Sport e quindi non dovrebbe vedere nessuna logica come Sport non è proprietario di Person e quindi it non dovrebbe vedi qualsiasi logica di Person .

Had Person to Sport è stato una relazione uno-a-molti, avrei argomentato diversamente, ma penso che il codice dovrebbe riflettere la simmetria della relazione sul database.

Modifica: risposta alla tua domanda:

Is this a code smell? What kind of relationship exists between the two objects? How would this be represented on an Object Diagram?

Una relazione di composizione implicherebbe che Sports componga Person che è come una relazione uno-a-molti tra Person e Sport . Nel tuo caso questo non è vero, essendo molti a molti.

La relazione è troppo complicata per tracciare semplicemente una linea tra i due rendendo necessario creare una classe media e quindi associare Person e Sport a quella middle class (come PersonSportManager ).

Spero che risponda alla tua domanda!

    
risposta data 21.11.2017 - 10:38
fonte

Leggi altre domande sui tag