Supponiamo di avere la seguente interfaccia utilizzata per pubblicare messaggi su una coda di messaggi:
interface IMessageProducer
{
void Publish<TMessage>(TMessage message);
}
Normalmente, un implementatore di questa interfaccia tenterà di pubblicare immediatamente un messaggio nella coda dei messaggi. Tuttavia, ho riscontrato che a volte ho bisogno che i messaggi vengano posticipati pubblicati fino a quando la transazione del database non è stata commessa (questo garantisce che i dati utilizzati nel gestore messaggi siano disponibili nel database).
È appropriato rendere esplicito questo comportamento allo sviluppatore? Ad esempio, estendendo l'interfaccia:
interface IMessageProducer
{
void Publish<TMessage>(TMessage message);
void DeferPublishUntilTransactionCommit<TMessage>(ITransaction transaction, TMessage message);
}
O creando un'interfaccia aggiuntiva che aggiunge questo comportamento (o anche un metodo di estensione all'interfaccia IMessageProducer
):
interface IDeferUntilTransactionCommitMessageProducer
{
void DeferPublish<TMessage>(ITransaction transaction, TMessage message);
}
La mia ipotesi è errata? Questo è davvero un dettaglio di implementazione in cui non c'è motivo di esporlo allo sviluppatore? Ho trovato molto utile (aumentare la chiarezza) rendere l'interfaccia esplicita sull'intento in modo che lo sviluppatore comprenda perché è importante rimandare la pubblicazione fino a quando la transazione non è stata commessa. Altrimenti, se si tratta di una preoccupazione trasversale e di un dettaglio di implementazione, diventa un problema di configurazione che può avere un impatto significativo sull'applicazione in esecuzione. Ho visto altri software / librerie che fanno queste scelte (come usare il commit a due fasi) un dettaglio di implementazione dell'interfaccia piuttosto che esplicito.