Sto lavorando su un sito web di dimensioni decenti (usando Java / Spring). Abbiamo fatto del nostro meglio per seguire l'architettura a più livelli, ma stiamo facendo fatica a fornire linee guida di progettazione valide per l'intero team. Descriverò la nostra attuale architettura e quindi elencerò i miei dubbi. Mi piacerebbe un aiuto.
- I repository / oggetti Dao sono responsabili di tutta la logica CRUD relativa a un particolare oggetto. Interagiscono principalmente con una singola tabella, ad eccezione dei casi in cui la stessa entità è suddivisa su più di essi (ad esempio:
User
può avere piùAddresses
ma l'intera logica è gestita daUserRepository
). - Le classi di servizio sono responsabili della logica di business. Spesso hanno bisogno di interagire con più
Repositories
per eseguire la loro logica. In genere, è qui che otteniamo il DBconnection
, lo passiamo a tutti i repository e commettiamo la transazione prima di restituire la risposta. Questo aiuta a ragionare e mantenere il db in uno stato coerente. - I controllori deserializzano il json in entrata in
Apimodels
e li consegnano alle classi di servizio. Nella maggior parte dei casi, la risposta inviata dal servizio viene restituita all'utente. A volte, un controller interagisce con più oggetti di servizio per costruire l'appropriata risposta api che viene inviata all'utente.
L'approccio sopra descritto funziona in modo decente, ma presenta diverse insidie.
-
Consideriamo ad esempio un
User
che ha una funzionalitàWallet
. Abbiamo bisogno dei dettagli diWallet
dell'utente in vari servizi (Coupon
,Booking
ecc.) Ma non tutti. Dove dovremmo inserire questa logica di join? Alcune persone vogliono mantenerlo nelUser
Repository, altri ritengono che questo appartenga al livello di Servizio (ma poi diventa un join a livello di app). -
In relazione a quanto sopra, spesso esiste una sorta di logica aziendale necessaria per diversi servizi. Es .: ottieni
User
conWallet
e passatobookings
. Possiamo mettere questo come una funzione in un servizio e avere altri servizi chiamarlo ma porta a una gerarchia / dipendenza all'interno delle classi di servizio. Rompe anche il flusso a senso unico e rende più difficile capire l'app. (Ho anche avuto un caso in cui le dipendenze circolari transitive si sono sviluppate nel tempo). - Un problema simile si verifica nelle interazioni tra
controller
eservice
layer. Funzionalità che si estende su più servizi è spesso scritta nel controller. È accettabile? - Il problema finale si verifica in termini di confezionamento di queste classi. So che il packaging per feature è molto più comprensibile. Ma la domanda arriva da dove aggiungere la funzionalità che è condivisa tra le app. Attualmente abbiamo uno strano mix di packaging funzionale e funzionale. È un casino.
Ho il sospetto che possiamo definire Component
classi come un'astrazione per mantenere la logica comune condivisa tra i servizi. Passaggi simili possono essere presi per la logica condivisa tra i controller. Ma vorrebbe davvero evitare la confusione di denominazione che si presenta in questa situazione. Idealmente, un suffisso dovrebbe dirti esattamente quale ruolo gioca la classe nell'app . Sto lottando per trovare una tale architettura / flusso.