Gestione dello stato incoerente degli oggetti del dominio

0

In generale, vorrei che i miei oggetti di dominio (cliente, contratto, ecc.) fossero sempre in uno stato coerente. Tuttavia ci sono situazioni in cui potrebbero trovarsi in uno stato incoerente e tuttavia voglio lavorare con loro:

  1. Quando carico l'oggetto dominio dal database e si trova in uno stato incoerente (forse qualcuno ha cambiato un campo direttamente nel database)
  2. Quando li creo in una finestra di dialogo di creazione e devo gestire alcuni errori di convalida.

Esistono buone pratiche su come gestire questi requisiti contraddittori?

    
posta Martin Böschen 08.03.2018 - 11:14
fonte

3 risposte

1

In generale, hai l'idea giusta. Supponiamo che "(...) potrebbero trovarsi in uno stato incoerente, e tuttavia voglio lavorare con loro". è falso e tu mai-mai vuoi vedere i tuoi oggetti in uno stato incoerente. Corriamo con questa idea e vediamo dove ci porta.

Durante il caricamento dal database

Quando carichi un oggetto da un database, devi costruire un valore che sarà un'istanza del tipo desiderato da un'istanza di un certo tipo che rappresenta il risultato ottenuto dal database. Devi deserializzare l'oggetto. Secondo me ha senso convalidare che gli invarianti richiesti dalla stiva - e un buon posto per farlo è il costruttore.

class Foo {
  public:
    Foo(Some_type_representing_db_result const);
};

Se hai bisogno di costruire Foo oggetti da Some_type_representing_db_result s, scrivi un costruttore appropriato per farlo per te (illustro la risposta usando C ++, ma sono sicuro che puoi adattare gli esempi alla tua lingua di scelta). Genera un'eccezione se il costruttore non è in grado di stabilire gli invarianti richiesti: non è necessario forzare te stesso a indebolirli per contenere alcuni valori eventualmente errati. In questo modo comprometterebbe la correttezza del tuo programma.

Se devi occuparti di oggetti rotti, ti suggerisco di creare un tipo di dati diverso, con invarianti più deboli; per esempio. Foo e WeakerFoo . In questo modo, il compilatore ti avviserà se tenti di utilizzare WeakerFoo come Foo non rotta.

Durante la gestione degli errori di convalida

Approfitta del fatto che non devi costruire immediatamente l'oggetto. Convalida i campi uno per uno e quando sei sicuro che abbiano valori accettabili, combinali nel tipo desiderato utilizzando il costruttore di quel tipo.

int count_of_stuff = a_form.count_of_stuff();
std::string name_of_stuff = a_form.name_of_stuff();

// These two functions should throw descriptive exceptions that
// will be useful to you.
check_if_count_of_stuff_is_in_acceptable_range(count_of_stuff);
check_if_name_of_stuff_is_valid(name_of_stuff);

Foo correct_foo { count_of_stuff, name_of_stuff };

Questa è davvero la stessa situazione di quella del database. È solo diverso perché hai un utente a cui puoi segnalare errori per campo.

Una nota a margine

Cerca di incorporare invarianti nei tuoi tipi. Se sai di avere un tipo i cui membri devono conformarsi ad alcune specifiche, crea un tipo per loro. Perché dovresti utilizzare un int e ricordare di convalidarlo in modo esplicito quando puoi utilizzare NumberForWhichSpecificRangeIsValid e farlo convalidare da solo?

    
risposta data 08.03.2018 - 12:14
fonte
3

When I load the domain-object from the database and it is inconsitent (maybe someone changed a field directly on the database)

La cosa migliore da fare è assicurarsi che i dati corrotti non possano essere inseriti nel db aggiungendo vincoli. Chiavi esterne, vincoli univoci o di lunghezza ecc.

When I create them in a Creation-Dialog and I need to handle some validation errors.

Scrivi un validatore sugli oggetti e convalidali prima di inserire / aggiornare.

Normalmente, non convalido i miei articoli recuperati dal DB poiché erano già stati controllati al momento dell'inserimento / aggiornamento. Ovviamente puoi anche convalidarli mentre li recuperi e li gestisci. Gestirlo con un'eccezione ha senso qui perché questo è qualcosa che non dovrebbe mai accadere.

    
risposta data 08.03.2018 - 11:41
fonte
0

Queste sono decisioni aziendali.

Per i dati nel database, è importante notare che i dati possono anche non essere più validi quando le regole aziendali cambiano. Quando cambiano, o quando le regole aziendali vengono violate da un cattivo attore, come si comporta l'affare con i suoi file cartacei?

Allo stesso modo, sull'assunzione dei dati, in che modo l'azienda dovrebbe gestire la versione cartacea dei dati? Sospetto che alcuni valori non validi richiederebbero la restituzione del modulo al cliente, decorati con messaggi di errore in inchiostro rosso. Per altre voci non valide, l'azienda potrebbe preferire che i suoi rappresentanti sorridano, ad esempio grazie, e fare tranquillamente alcune supposizioni dietro le quinte.

Poni le tue domande a "l'azienda" come guida.

Idealmente, vieni alla discussione armata di una conoscenza di quali opzioni sono possibili digitalmente che non potrebbero essere fatte su carta e viceversa. Rivolgiti agli esperti UX, se necessario, per soluzioni creative per convincere i clienti bene per le correzioni e per farli sentire ricompensati per aver corretto i loro errori. Ecc.

Soprattutto, non prendere decisioni aziendali senza "il business". Quindi, la "migliore pratica" è quella di consultare l'azienda (e / o un esperto di dominio, che un giorno sarà essere).

    
risposta data 08.03.2018 - 17:25
fonte

Leggi altre domande sui tag