"Separa query dal modificatore" e restituisce valori [chiuso]

-1

Ho sentito dire che è necessario mantenere le funzioni di query e di modifica separate l'una dall'altra, e sono d'accordo con il sentimento. Quando provo ad applicarlo, mi imbatto spesso in due problemi / domande:

  • Che cosa, se possibile, dovrebbe restituire un modificatore? Non dovrebbe restituire un indicatore di successo / fallimento? Dovrebbe invece restituire nulla, ma lanciare un'eccezione in caso di fallimento?

  • I costruttori dovrebbero essere trattati come modificatori (la creazione di un oggetto è un effetto collaterale)? Sospetto di no, dal momento che un costruttore che ha creato un oggetto ma non ha restituito un riferimento ad esso sarebbe piuttosto noioso.

posta ivan 21.12.2015 - 16:09
fonte

2 risposte

1

In realtà rispondere a questo è piuttosto semplice, ma non breve.

What, if anything, should a modifier return? Should it not return an indicator of success/failure? Should it instead return nothing, but throw an exception upon failure?

Per prima cosa devi chiederti perché non devi restituire nulla dal comando (modificatore). Cosa ci guadagna?

C'è in realtà un vantaggio che vale la pena - possiamo eseguire quel comando in modo asincrono in uno sfondo, cioè mettere il comando che crea un nuovo post nella coda dei comandi, che è gestito da altri processi, magari scritto in un'altra lingua. Con ciò puoi semplicemente mettere il comando in coda e restituire la risposta http non aspettando che la creazione del post avvenga, un grosso guadagno di prestazioni, giusto?

Non scambiare il valore restituito dal comando e restituire la risposta http. Devi fare quest'ultimo per informare il cliente che mettere il comando in coda ha avuto successo o meno, ma solo quello. Aumentare l'eccezione dal comando equivale a restituire il valore, quindi non puoi farlo.

Ora è la domanda, come restituire l'id del post appena creato al client, perché vogliamo consentire all'utente di modificare immediatamente quel post.

Quindi, i comandi non hanno un valore di ritorno, ok. Ma hanno un risultato, un effetto. Nell'esempio se call turnLightOn comando non restituisce vero o falso per indicare che ha funzionato - è sciocco, ma possiamo vedere con i nostri occhi che le luci sono accese e che possiamo vedere di notte. Questo è un effetto del comando. Come rappresentiamo l'effetto nella programmazione? Per gli eventi, naturalmente. Il comando che ha acceso le luci, pubblica anche l'evento LightsTurnedOn (passato) e il client è iscritto a quell'evento.

Tornando al nostro esempio di creazione post:

    Il client
  • invia una richiesta al server http che desidera creare post con il titolo "Super post"
  • Il server
  • riceve tale richiesta e la inserisce nel bus di comando (coda) e restituisce la risposta HTTP con il codice 200
  • Il processo
  • che gestisce i comandi raccoglie il comando appena inserito ogni volta che è in grado di (ha lavoratori gratuiti), fa quello che deve fare - crea post e pubblica l'evento PostCreated(userId, postId)
  • il client deve in qualche modo iscriversi per quell'evento e ci sono diversi modi:

    • query di servizio eventi di volta in volta, per verificare se il nuovo evento è pubblicato per noi utilizzando AJAX (opzione peggiore),
    • connettiti al server websocket e attendi l'evento lì,
    • connettersi al server Server Sent Events (SSE) e attendere l'evento (l'opzione migliore)
  • il servizio eventi è sottocorso all'evento PostCreated in modo che sappia quando inoltrare tale evento al client tramite il protocollo scelto, cioè SSE,
  • Il client
  • riceve l'evento che il suo post è stato creato e può fare quello che vuole con quello

Profit.

Should constructors be treated as modifiers (is the creation of an object a side-effect)? I suspect not, since a constructor that created an object but didn't return a reference to it would be pretty annoying.

L'effetto collaterale è tutto ciò che non è referenziale trasparente .

Significa che se il tuo costruttore non fa nient'altro, ma restituisce solo il riferimento all'oggetto appena creato, allora non ci sono effetti collaterali. Ma se quel costruttore usa valori globali (ottieni o imposta, non importa) per creare quell'oggetto, allora non è referenziale trasparente e ha un effetto collaterale. Perché?

import config

class Foo:
    self.bar = config.BAZ

foo1 = Foo()
config.BAZ = 'something different'
foo2 = Foo()

foo1 != foo2
    
risposta data 21.12.2015 - 17:22
fonte
1

What, if anything, should a modifier return? Should it not return an indicator of success/failure? Should it instead return nothing, but throw an exception upon failure?

Solitamente viene visualizzato void restituito quando si prevede che un oggetto modifichi il proprio stato. Idiomaticamente, questo è in qualche modo utile - il valore di ritorno dice allo sviluppatore di aspettarsi effetti collaterali nell'operazione.

Lanciare un'eccezione è la pratica generalmente accettata per riportare la condizione di "fallimento".

In CQRS basato su eventi, a volte si vedrà questa alternativa: i metodi di comando restituiscono un elenco (eventualmente vuoto) di eventi che descrivono i cambiamenti di stato effettuati dall'oggetto in risposta al comando.

Should constructors be treated as modifiers (is the creation of an object a side-effect)? I suspect not, since a constructor that created an object but didn't return a reference to it would be pretty annoying.

I costruttori sono strani. In molti casi, la chiamata del costruttore può essere sostituita con una chiamata a una fabbrica - questo in realtà non risponde alla domanda da sola, ma se riesci a persuaderti che le due scelte dovrebbero almeno condividere la stessa risposta, offre alcune vincoli.

Chiaramente la creazione del nuovo oggetto è un effetto collaterale, se l'oggetto può essere pensato per creare se stesso. Ma la fabbrica non cambia necessariamente solo perché l'hai interrogata per un nuovo oggetto.

In alternativa, puoi pensare ad ogni modifica di un oggetto come una variazione dallo stato corrente al nuovo stato. Se si considera che il costruttore sta stabilendo il primo stato, non si tratta di una transizione tra stati e non deve essere considerato una modifica. D'altra parte, se immagini tutti gli oggetti a partire dallo stesso stato "seed", allora il costruttore è la modifica che prende un'istanza dallo stato seme al suo primo stato univoco.

Non andare dagli elfi per un consiglio, perché risponderanno sia no che sì

    
risposta data 21.12.2015 - 17:25
fonte

Leggi altre domande sui tag