È necessario più estrarre la logica dai controller API?

6

Ho lavorato in framework MVC sin da quando hanno iniziato a diventare popolari con RoR e ASP.NET MVC. Sono sempre stato attento a non mettere mai la "logica di business" sui miei controller poiché accoppia il framework con la logica. In questi giorni, come molti di voi, non sto realmente utilizzando la parte MVC del mio framework, dal momento che non sto restituendo "views" e manufatti framework. Invece, sto solo utilizzando le rotte per le azioni del controller per creare API che restituiscano xml o json.

Negli ultimi due anni, ho cercato di avvicinarmi a CQRS, quindi la mia logica di business finisce per essere impacchettata in comandi e gestori con un dispatcher per connettere i due. La "vera" business logic è in realtà nelle mie entità, ma i miei gestori di comandi guidano le operazioni. Ho anche iniziato a consentire a più servizi di esporre diversi contesti limitati (micro-servizi). Poi ho iniziato a pensare "fuori dagli schemi" (fuori per me, almeno).

Perché mi preoccupo di dispatcher, comandi e gestori di comandi? Ora che il mio framework è solo uno strato di rete sul mio contesto limitato, perché non lasciare che i miei controller siano i miei gestori di comandi? Perché non lasciare che il mio supervisore sia il sistema di routing nel mio framework? Perché non lasciare che il contenuto della richiesta HTTP sia il mio comando?

    
posta Byron Sommardahl 02.05.2015 - 18:23
fonte

2 risposte

1

Risposta breve

Il vantaggio principale del disaccoppiamento della logica applicativa da qualsiasi livello di presentazione / di interfaccia esterna è quello di consentire ai consumatori di variare in modo indipendente senza duplicare la logica. Pertanto, la necessità del disaccoppiamento dipende da quanti utenti avrà la tua applicazione.

Risposta lunga

Usando la nomenclatura Domain-Driven Design, la tua domanda potrebbe essere riformulata come " Perché includere un 'Application Layer' all'interno della tua architettura della soluzione? ".

L'Application Layer è inteso come interfaccia per il dominio e le esigenze infrastrutturali della tua applicazione, traducendo i messaggi di richiesta e risposta in interazioni con i componenti sottostanti. Con "tradurre" qui, intendiamo la conversazione di un messaggio logico in un formato standard in zero o più operazioni sui componenti sottostanti. Idealmente, una richiesta a un "Servizio di trasferimento fondi", che verifica l'input, indica al dominio di eseguire un trasferimento, persiste lo stato del dominio, registra l'operazione e notifica il mondo chiamando "Notifica servizio infrastruttura mondiale", potrebbe essere chiamato da un test a livello di componente o sottocutaneo, un'applicazione Web, un'applicazione console o essere esposto come servizio Web senza modifiche. Detto questo, la misura in cui una data soluzione beneficia di tale separazione delle strategie di preoccupazione dipende dal contesto.

Esistono, tuttavia, altri fattori che potrebbero portare a desiderare un certo grado di disaccoppiamento dall'interfaccia di consumo oltre alla necessità di fornire assistenza a più consumatori. Ad esempio, l'architettura ASP.Net MVC tende a indirizzare gli sviluppatori in operazioni di raggruppamento insieme per una determinata vista / pagina Web. Per le operazioni che vanno oltre le semplici operazioni CRUD su una singola radice aggregata, il design di Microsoft tende a condurre controllori privi di coesione rispetto allo stereotipo del ruolo dell'adattatore che devono servire.

Per spiegare meglio, mentre potresti avere un CustomerController le cui azioni riguardano esclusivamente i clienti e nient'altro che i clienti, ogni azione potrebbe richiedere a diversi collaboratori di raggiungere il loro obiettivo, non tutti sono necessari per ogni operazione. Una azione potrebbe dover salvare qualcosa in un database, un'altra potrebbe dover inviare una e-mail e un'altra potrebbe aver bisogno di memorizzare dati o inserire qualcosa in una coda di messaggi. Solo perché tutte queste azioni ruotano intorno a una singola radice aggregata, non significa che il ruolo che il controller è chiamato a svolgere (cioè l'adattatore) è coeso rispetto alle proprie responsabilità. Idealmente, un framework Web prenderebbe un messaggio HTTP in entrata e lo mapperebbe su un gestore di comandi all'interno del livello del servizio applicativo senza richiedere che Application Service Layer assuma una dipendenza dal framework Web .

La teoria dell'architettura e le motivazioni Feng Shui a parte, tutto si riduce alla necessità di riutilizzare la logica dell'applicazione che si sta per posizionare nella propria pagina Web / codice dietro / controller / gestore di comandi. In genere, il primo client che dovrebbe utilizzare la logica dell'applicazione è la specifica dell'eseguibile e la seconda è l'interfaccia di produzione. A seconda dell'approccio al test (nessuno, accettazione degli utenti, isolamento, ecc.) E della facilità con cui le dipendenze del framework che si prendono come parte dello sforzo di implementazione della logica dell'applicazione consentono di implementare le osservazioni della specifica, questo spesso determinerà il grado di disaccoppiamento che vuoi includere nella tua applicazione.

    
risposta data 02.05.2015 - 20:26
fonte
1

Bene ... l'idea principale di CQRS per separare le operazioni di lettura e scrittura. È possibile utilizzare questo modello per un motivo principale,

The change that CQRS introduces is to split that conceptual model into separate models for update and display - Martin Fowler

Quindi, se hai due di questi modelli da mantenere, sarebbe molto difficile non usare comandi, gestori di comandi e così via.

Ma dal momento che pensi di poterli eliminare e spostare la logica sui controller (ovviamente non sulla logica del dominio), probabilmente non stai effettivamente utilizzando CQRS e probabilmente non dovresti usarlo se non hai bisogno a.

    
risposta data 12.05.2015 - 04:41
fonte

Leggi altre domande sui tag