Come progettare il livello di servizio quando si lavora con oggetti e relazioni modello

1

Ho una relazione semplice in cui gli articoli di livello superiore ( Recipe ) hanno una relazione uno-a-molti con i bambini ( Ingredient ) e ogni elemento ha un identificativo univoco ( ID ).

Per le semplici operazioni CRUD il flusso è:

  RecipeService   ->   RecipeManager   ->   Recipe

IngredientService -> IngredientManager -> Ingredient

Faccio fatica con due decisioni primarie durante la progettazione delle classi di servizio / gestore:

Primo: Modelli vs. Primitivi

Fornite valori primitivi, o oggetti modello, durante l'inserimento di un articolo che influenza una relazione? Ad esempio:

class IngredientService {
    func addIngredientToRecipe(ID recipeID, String ingredientName, int ingredientAmount)
}

Versus:

class IngredientService {
    func addIngredientToRecipe(Ingredient i, Recipe toRecipe)
}

Il primo richiede un elenco sempre crescente di argomenti, ma gestisce internamente le ricerche e la convalida (esiste la ricetta, come otteniamo, ecc.)

Il secondo è più pulito, ma richiede che i chiamanti abbiano già cercato una ricetta e creato un ingrediente.

C'è anche la permutazione:

class IngredientService {
    func addIngredientToRecipe(ID recipeID, Ingredient ingredient)
}

Secondo: Service vs. Manager per un tipo ancillare

I servizi possono dipendere l'uno dall'altro o dovrebbero immergersi direttamente nei manager? Diciamo che implementiamo:

func addIngredientToRecipe(ID recipeID, String ingredientName, int ingredientAmount) {
    ...
}

Quando cerchi la ricetta esistente, dovremmo usare RecipeService o RecipeManager ? È sicuro che entrambi avranno una ricerca basata su ID, anche se il servizio semplicemente ombreggia / inoltra al gestore.

Questi tipi di decisioni iniziali sono importanti per stabilire buoni modelli e stili, ma faccio fatica a identificare se ci sono insidie in un modo o nell'altro.

    
posta Craig Otis 15.06.2018 - 00:11
fonte

1 risposta

1

Risposta super veloce. Potrei espanderti più tardi.

Primitivi contro modelli.

Usa i modelli. Non sai quali informazioni richiederanno la funzione quando specifichi il metodo / la firma della funzione. Quindi è meglio includere tutte le informazioni. Ad esempio, se stai creando un'interfaccia, può rimanere costante su molte versioni di un servizio.

Manager (repository) e dove metterli.

Non mettere i repository nei tuoi servizi. La logica del servizio dovrebbe essere in grado di funzionare idempotently, quindi qualsiasi stato interno sarà problematico. Questo risolve anche il tuo primo problema su dove trovare i modelli.

Recupera gli oggetti dal repository, passali a un servizio o servizi per manipolarli e poi reinserirli nel repository.

In modo confusivo che l'orchestrazione di quei servizi come descritto sopra, può essere un servizio o un livello di servizio stesso. Quindi la regola non è infallibile, ma ti viene l'idea.

Altrimenti penso che tu abbia un buon modello di stile ADM lì. C'è sempre una domanda sulle funzioni che modificano i loro parametri, ma un rapido cambio di stile alle funzioni che restituiscono nuovi oggetti può risolverlo senza modifiche reali al codice, se necessario.

    
risposta data 15.06.2018 - 01:12
fonte