Scegli il miglior nome della funzione nel repository [duplicato]

2

Nel mio codice, sto usando un pattern di repository. Ad esempio, ho ottenuto il repository degli affari. Sono solo curioso di sapere come decidi il nome della funzione quando la funzione stessa fa tante cose. Penso che quando il nome della funzione è troppo lungo può diminuire la leggibilità del codice. È considerato negativo a causa del nome della funzione troppo lungo in termini di codice pulito.

Per esempio sotto c'è l'elenco della funzione che ho scritto nella classe DealRepository:

  • GetAllDealsWithinValidRangeStartDateEndDateUserLimitAndQuota
  • GetAllDealsForCategoryWithinValidRangeStartDateEndDateUserLimitAndQuota
  • GetUniqueSubCategoriesForDealsWithinValidRangeStartDateEndDateUserLimitSubCategoryAndQuota
  • GetAllDealsForSubCategoryWithinValidRangeStartDateEndDateUserLimitAndQuota

Il nome della funzione è troppo lungo perché quando si desidera recuperare l'offerta, si ottengono molte cose da filtrare come deal entro raggio di 10 km, data di inizio offerta, data di fine contratto, quota di offerta, quota di negoziazione per utente e altri. Qualsiasi suggerimento o opinione su come scegliere un buon nome per questa funzione.

    
posta zer0fl4g 16.11.2016 - 02:56
fonte

2 risposte

3

La firma del metodo non è solo il suo nome, ma anche il tipo di ritorno, gli argomenti, i parametri generici, ecc. Nel tuo caso, sembra che i nomi, per la maggior parte, ripetano ciò che è già specificato dal argomenti.

Se il tuo linguaggio di programmazione supporta l'overloading, puoi finire con qualcosa di simile:

  • DealRepository.GetAll(DateRange range, int userLimit, int quota)

  • DealRepository.GetAll(Category category, DateRange range, User user, int quota)

  • DealRepository.GetAll(SubCategory sub, DateRange range, User user, int quota)

  • DealRepository.GetSubCategories(DateRange range, User user, int quota)

Forzando il chiamante a specificare l'intervallo, si mostra che i valori restituiti rientrano nell'intervallo (altrimenti, il metodo non avrebbe alcun senso). Lo stesso vale per il limite utente e la quota.

Se la tua lingua ha anche parametri opzionali, puoi ridurre ancora di più il numero di metodi:

  • DealRepository.GetAll(DateRange range, int userLimit, int quota, Category category: null)

  • DealRepository.GetAll(SubCategory sub, DateRange range, int userLimit, int quota)

  • DealRepository.GetSubCategories(DateRange range, int userLimit, int quota)

e quindi, rendendo Category e SubCategory ereditati dalla stessa abstract classe Grouping , puoi refactoring su:

  • DealRepository.GetAll(DateRange range, int userLimit, int quota, Grouping grouping: null)

  • DealRepository.GetSubCategories(DateRange range, int userLimit, int quota)

Che cosa è successo con Unique ?

Usando il principio del minimo stupore, puoi davvero, come nel mio esempio qui sotto, omettere Unique dal nome. In altre parole:

  • Se l'utente si aspetta, chiamando GetSubCategories , per ricevere solo valori distinti, non aggiungere Unique al nome del metodo.

  • Se l'utente presuppone che il metodo possa produrre valori duplicati, allora è preferibile GetUniqueSubCategories per mostrare che i valori sono necessariamente univoci. Oppure puoi cambiare la firma del metodo per restituire un tipo che corrisponde a una sequenza contenente solo valori distinti.

GetSubCategories appartiene davvero qui?

Se GetAll restituisce una sequenza digitata (come DealsCollection ), puoi spostare GetSubCategories in questa classe. Invece di fare:

new DealRepository().GetSubCategories(...)

il chiamante preferisce fare:

new DealRepository().GetAll(...).GetSubCategories()

Alcune note ...

A parte il fatto che WithinValidRangeStartDateEndDateUserLimitAndQuota non ha posto nel nome del metodo, ci sono anche alcuni problemi:

  • WithinValidRange : perché non semplicemente WithinRange ? Avrebbe senso che un chiamante interroghi le offerte in un intervallo non valido ?

  • StartDateEndDate : non dovresti farlo neanche a livello di oggetto. Non è Date start, Date end . È un intervallo di date. Quindi crea una classe DateRange .

  • All sembra sbagliato. Attualmente, il chiamante non recupera tutte le offerte , ma solo le offerte che corrispondono ai filtri specificati.

  • A seconda della comunità che usa la lingua, può essere accettabile rimuovere il prefisso Get , che porta a DealRepository.All(...) e DealsCollection.SubCategories() .

  • Se sei in grado di utilizzare il pattern iteratore, il metodo diventa:

    DealRepository.GetAll()
    

    senza argomenti. È usato in questo modo:

    DealRepository
        .GetAll()
        .Where(d => range.Contains(d.date) && d.user == user)
        .Take(quota)
    
risposta data 16.11.2016 - 03:04
fonte
2

Potrebbe essere una buona idea avere un singolo metodo che accetta invece un oggetto come parametro, se le query sono sufficientemente configurabili. Questo è chiamato refactoring Introduci oggetto parametro .

public class GetDealsParameter
{
    public DateTime? Start { get; set; }
    public DateTime? End { get; set; }
    public int? Limit { get; set; }
    public string Category { get; set; }
}

public class DealRepository 
{
    public IEnumerable<Deal> GetDeals(GetDealsParameter dealsParam)
    {
        // ...
    }
}

In questo esempio devi solo impostare i valori su cui desideri filtrare.

Se hai bisogno di aiuto per costruire l'oggetto Parametri puoi anche utilizzare il modello di build .

    
risposta data 16.11.2016 - 03:17
fonte

Leggi altre domande sui tag