2010-09-01 10 views
5

Si tratta di una progettazione di oggetto valida? Ho un oggetto dominio in cui inietto un servizio e chiamo un metodo di verifica per aggiornare lo stato dell'oggetto e se tutto va bene invia un messaggio di conferma. Il codice è simile a:Incapsulamento di una chiamata di servizio all'interno di un metodo di un oggetto dominio

class Foo { 
    String bar 
    Service emailService 


    public boolean verify() { 
    bar = "foo" 
     if(this.save()) { 
      emailService.sendConfirmation() 
     } 
    } 
} 

Foo.get(1).verify() 

È accettabile chiamare il servizio di posta elettronica in tale distanza? c'è un modello di design che posso seguire per utilizzare una situazione del genere.

Grazie - Ken

risposta

10

Non c'è niente di sbagliato con chiamare un servizio da un'entità. Vi sono, tuttavia, alcuni problemi relativi alla creazione di istanze di questi servizi. Se segui questo percorso, devi in ​​qualche modo ottenere un'istanza di un servizio durante la creazione di entità che è problematico.

chiamando direttamente un costruttore è ovviamente una cattiva idea (dato che le coppie l'entità alla implementazione del servizio).

Jimmy Bogard spiegato perché injecting services into entities is a bad idea.

Invece di farlo, ha suggerito di utilizzare il modello "double dispatch" (c'erano alcuni dibattiti se questo nome è appropriato) per risolvere questo problema. In questo approccio, un metodo di dominio callee fornisce un'implementazione del servizio al metodo del dominio. Nel tuo caso sarebbe sembrare qualcosa di simile:

class Foo { 
    String bar  

    public boolean verify(Service emailService) { 
    bar = "foo" 
     if(this.save()) { 
      emailService.sendConfirmation() 
     } 
    } 
} 

Foo.get(1).verify(new Service(...)) 

L'ultima opzione (ma non meno importante) è quello di utilizzare Domain Eventi modello. Puoi leggere a riguardo su Udi Dahan's blog. In questo approccio le entità sono responsabili solo della pubblicazione di eventi significativi sottoscritti da gestori appropriati. Puoi leggere il confronto completo di tutte queste tecniche on my blog.

Speranza che aiuta

+0

Direi che dovresti codificare un'interfaccia qui. Ciò renderà la tua entità testabile e sarà facile cambiare il servizio se necessario. ** public bool verificare (IConfirmationService emailService) ... ** –

+1

mi piace molto il modello di dominio degli eventi e piaciuto leggere l'articolo Udi Dahan e soprattutto i commenti e le sue risposte a loro. Sono anche dell'opinione che la tecnica di doppia spedizione debba essere utilizzata quando la tecnica degli eventi di dominio non risolve il problema in questione.Hai anche fatto notare il localizzatore di servizi che ritengo personalmente siano malvagi in quanto fornisce un falso senso di incapsulamento. Fa anche provare l'inferno. Grazie per voi intuizioni e risposte. – ken

2

io di solito mando la conferma dal luogo (azione?), Dove da verificare sarà chiamato. Se l'esito della verifica potrebbe essere quella di inviare molti messaggi di posta elettronica di conferma poi avrei probabilmente avuto Foo generare e restituire ConfirmationMessage s (un oggetto di dominio) che incapsulare tutto il sapere per una conferma. L'azione sarebbe quindi in grado di accodare questi messaggi per la spedizione.

Detto questo, se il tuo Service è un'interfaccia e puoi iniettare simulazioni per il test e quello reale in fase di produzione, allora sembra buono. Anche se penso che sia meglio che gli oggetti di dominio contengano conoscenza e logica su se stessi e non sui sistemi (servizi) in un altro livello.

+0

+1 Questa è la strada da percorrere in DDD – Jehof

+0

+1 Verificare che un oggetto non abbia nulla a che fare con l'invio di e-mail. E immagina di verificare più oggetti all'interno di un'operazione batch: invierai un'email per ciascuno di essi! –

+0

Non sarebbe un'API strana per fare in modo che un metodo di verifica restituisca un oggetto ConfirmationMessage. Ciò che un client API si aspetta è se l'operazione è andata a buon fine o meno. In ciò che stai suggerendo, quando l'operazione di verifica fallisce, tu restituirai un valore nullo? – ken

3

cosa negativa di questo è che si perde l'isolamento del modello di dominio. Il tuo modello di dominio conosce il servizio di posta elettronica che è pura infrastruttura.

Potrebbe essere una buona idea di introdurre un servizio di applicazione. Anche lo schema degli eventi andrebbe bene.

Problemi correlati