Passare un oggetto invece dei parametri

0

Vedi il codice qui sotto:

public class Person
{
   public DateTime DateOfBirth;
   public List<Offer> Offers = new List<Offer>();
   public Person(DateTime DateOfBirth)
   {
        int age = DateTime.Now.Year-candidate.Year;
        if (DateTime.Now < candidate.AddYears(age)) age--;
            if (age < 18 || age > 99)
                throw new ArgumentException("Age must be greater than 18.", "DateOfBirth");
    _dateOfBirth=dateOfBirth;
   }

   public void GetOffers(IOfferCalculator offerCalculator)
   {
     return offerCalculator.GetOffers(this);
   }

   public void AssignOffers(List<Offer> offers)
   {
      //Assign offers to Person.Offers here.
   }
}

Si noti che io passo l'intero oggetto Person a Person.GetOffers (). La ragione per cui lo faccio è perché la persona deve essere oltre 21 per tutte le offerte e questa viene verificata (validata) nel costruttore Persona. È una buona ragione per passare l'Inquiry come oggetto a: offerCalculator.GetOffers? Il motivo per cui lo chiedo è che t3chb0t ha descritto questo come un odore di codice nella mia domanda qui: link

In alternativa, potrei semplicemente passare DateOfBirth in questo modo: return offerCalculator.GetOffers (DateOfBirth). Tuttavia, ciò significherebbe che dovrei convalidare DateOfBirth in ogni offerta.

Sto cercando di seguire il principio del minimo stupore in questi giorni e mi ritrovo a pensare troppo. Le mie due domande sono:

1) È un buon appraoch passare l'oggetto Person a offerCalculator.GetOffers come Persona ha già convalidato la data di nascita?

2) Devo controllare la data di nascita di ogni offerta, anche se ogni offerta richiede che la persona abbia più di 21 anni? Non penso che questo cambierà il cambiamento, cioè la persona dovrà sempre avere più di 21 anni.

    
posta w0051977 05.02.2018 - 15:16
fonte

1 risposta

4

Come qualsiasi cosa, questo alla fine si riduce al caso d'uso e agli standard di codifica della squadra. Tuttavia, in generale, sosterrò il passaggio degli oggetti invece dei tipi di dati di base.

Hai già fornito un motivo, per consentirti di convalidare in un posto anziché multiplo, ma consentimi di aggiungere altri motivi.

Se passi solo una data, è possibile che qualcuno possa passare una data errata, ad esempio la data in cui la persona è stata creata nel sistema. Questo non verrebbe rilevato come errore di compilazione, tuttavia se passasse accidentalmente in un utente anziché in una persona, la compilazione fallirebbe e il bug sarebbe stato prevenuto.

In secondo luogo, se i requisiti fossero mai cambiati in modo che GetOffers () richiedesse una proprietà aggiuntiva (diciamo che era basata sulla loro posizione e sul loro DOB), questo potrebbe facilmente essere refactored per usare altre proprietà sull'oggetto Person invece di dover cambia firma.

Tuttavia, non sono un grande fan del layout del codice. Sospetto che uno dei motivi per cui questo si stia facendo un po 'strano è che non hai uno strato di business logic chiaramente definito. Non avrebbe più senso avere l'interfaccia utente (o qualsiasi altro codice che si sta chiamando) chiama un IOfferCalculator che prende una persona? Che nella mia mente ha molto più senso che avere un'interfaccia utente creare una persona e passare in un IOfferCalculator che poi a sua volta prende la persona stessa?

Il mio suggerimento sarebbe:

public void MyUIMethod(int personId)
{
  // _personDataAccess and _offerCalculator will have been passed in via DI
  var person = _personDataAccess.GetPerson(personId);
  var offers = _offerCalculator.GetOffers(person);

  // do something with the offers
}

TLDR Personalmente mi piace passare l'oggetto, ma alla fine si tratta di progettare e degli standard di codifica delle squadre. Tuttavia, se fossi in te, darei un'occhiata al tuo design BLL, che, sospetto, sia causa di alcuni dei tuoi mal di testa.

    
risposta data 05.02.2018 - 15:29
fonte

Leggi altre domande sui tag