Nomenclatura per la funzionalità di ispezione degli oggetti

0

Sto aggiungendo il supporto per mod per un gioco su cui sto lavorando. Analizzo un file di dati simile a questo:

"requirements":
{
    "is_class": { "class": "warrior" },
    "is_in_faction": { "faction": "elves" }
}

Da questi dati, creo un elenco di oggetti Requirement che convertono i dati in delegati associati tramite riflessione. Il delegato prende un'istanza dell'oggetto e i valori associati come parametri. Memorizzo l'elenco di Requirement oggetti in RequirementDatabase relativi agli articoli che richiedono tali requisiti. Questa parte è risolta.

L'aspetto con cui sto combattendo è nominare questa funzionalità. Al momento ho:

RequirementDatabase.Evaluate(Object target)
{
    foreach(Requirement requirement in requirements)
    {
        if(requirement.Evaluate(target) == false)
            return false; // requirements not met
    }

    return true; // requirements met
}

Non mi sento come "Valutare", specialmente quando viene nutrito un oggetto che viene valutato, trasmette la semantica giusta di ciò che sta accadendo. Avrebbe leggermente più senso il contrario: Object.Evaluate(Requirement) ma non voglio che gli oggetti vengano resi consapevoli dei requisiti.

Qualche consiglio? Sono felice di rinominare tutto e tutto qui per ottenere una semantica chiara.

    
posta Michael.Aaron.Williamson 30.08.2018 - 00:02
fonte

2 risposte

2

Sospetto che abbiate problemi con il nome proprio perché la maggior parte di questa funzione fa qualcosa di molto generico / astratto che state usando in un contesto specifico / concreto, e queste forze vi spingono in direzioni diverse su come descrivere esso. Lo noto molto. Quando incontro questo, cerco di prendere in giro gli aspetti astratti e concreti a parte. Descrivo cosa succede senza riferimento alla situazione specifica / dettagli concreti e questo di solito mi aiuta a fare due cose: (1) estrarre la parte generica e (2) nominare ogni parte singolarmente. Quando separo le due parti l'una dall'altra, i nomi sensibili per entrambi tendono a venire da me più facilmente.

In primo luogo, vedo "return true if 'evaluate ()' restituisce true per tutti i requisiti". Consentitemi di sostituire "requisito" con "cosa" (nascondere i dettagli) e vedere cosa succede. "return true if 'evaluate ()' restituisce true per tutte le cose". OK. Visto che mi diverto a "valutare", lascia che provi a sostituirlo con qualcosa di ancora meno concreto. "return true if 'un predicato P' restituisce true per tutte le cose". Ora ho bisogno di aggiungere alcuni dettagli per evitare confusione. "return true if 'un predicato P' restituisce true per tutte le cose in 'some collection C'". OK. Non penso di poterlo rendere più astratto. Cosa rimane? Voglio solo sapere se il predicato è vero per tutti gli elementi nella collezione. IsTrueForAllItems(predicate, items) , dove predicate è una funzione che trasforma item in boolean . In una lingua con parametri di tipo, posso dichiarare il tipo di questa funzione senza conoscere il tipo di elementi, quindi posso estrarlo completamente dal suo contesto attuale di "requisiti.

Quindi ora estrao IsTrueForAllItems() (e lo metto da qualche parte ), che ha un nome sensibile ma forse goffo, che trasforma RequirementDatabase.Evaluate() in una funzione a una riga che nasconde la maggior parte dei suoi dettagli. Una volta nascosto i dettagli di questo utilizzo di IsTrueForAllItems() , posso concentrarmi su ciò che conta usarlo in quel modo, quindi trovare un nome migliore per questo. Poiché non conosco molto bene il dominio dell'applicazione, posso solo suggerire che potresti trovare un nome ragionevole da qualche parte in quello che hai digitato nella tua domanda:

I store the list of Requirement objects in a RequirementDatabase related to the item(s) that need those requirements.

Questo fa scattare qualche idea?

Inoltre, quando guardo i commenti nel tuo algoritmo, vedo "interpretare i commenti", che suggeriscono nomi per me. Forse la funzione diventa RequirementsMetBy(predicate, requirements) . Ti sembra meglio? Per "commento interpretativo" intendo un commento che spiega come interpretare un valore che non si descrive adeguatamente. Li incontro spesso quando ho troppi dettagli in un posto e devo spiegare cosa significano. (Non sembra che tu abbia "troppi" dettagli qui, ma hai all'inizio di troppi dettagli qui. Hai già bisogno di commenti per spiegare quale ruolo giocano! Può solo diventare più difficile da capire nel tempo quando aggiungi il codice.)

Successivamente, ora che puoi pensare a IsTrueForAllItems() senza Requirement oggetti che ti distraggono, potresti notare che questo si riduce a mappare il predicato a ciascun elemento nella raccolta, quindi a piegare i valori booleani risultanti con and . Potresti anche essere in grado di trovare una libreria per farlo con i nomi che ti piacciono.

Infine, se desideri riorganizzare la funzione di primo livello per rendere l'API più gradevole, puoi farlo in modo indipendente senza dover modificare IsTrueForAllItems() . Allo stesso modo, se la tua lingua ti consente di spostare IsTrueForAllItems() su una classe, devi semplicemente riorganizzare i parametri (uno dei parametri diventa il ricevente, la raccolta o il predicato) e puoi apportare tale modifica in modo sicuro e meccanico. Diventa più facile e più sicuro giocare su come rendere l'API più gradevole in base ai tuoi gusti o per adattarsi meglio alla struttura del resto del sistema.

    
risposta data 30.08.2018 - 15:57
fonte
0

A seconda del supporto linguistico è possibile capovolgere l'ordine degli oggetti con un metodo di estensione

static bool Matches(this Object, List<Requirement> requirements) {...}

Oppure potresti fare qualcosa di simile con un nuovo oggetto ObjectList che fa parte della libreria Requisiti

public class ObjectList 
{
    public List<Object> Objects {get;set;}
    public List<Object> FilterBy(List<Requirement> requirements) {...}
}
    
risposta data 30.08.2018 - 15:07
fonte

Leggi altre domande sui tag