Che cosa dovrebbe sapere il mio oggetto utente?

6

Ho un problema di architettura / dubbio e mi piacerebbe avere qualche idea su questo.

Contesto:

Siamo in un'app mobile che si basa esclusivamente sulle chiamate al servizio web da utilizzare. È possibile accedere a un solo utente in qualsiasi momento e tutte le chiamate richiedono un utente. Stiamo parlando di riunioni (a scopo di esempio e chiarezza) (un utente ha una riunione) e visitatori (un visitatore è un contatto, non un altro utente).

Il dibattito:

Abbiamo discusso per circa un'ora. Un lato vuole avere diversi "Manager" o "Servizi" che gestiscono, per esempio, le riunioni e portano un utente in parametro. Questo servizio / gestore viene chiamato quando necessario per ottenere un elenco di riunioni e viene assegnato all'utente corrente. Questo sembra pulito, non accoppiato (ben separato), e abbastanza chiaro senza essere ingombro e complicato.

L'altro lato dice che non ci sono azioni che un utente può fare senza essere loggato, e tutti quei servizi avranno bisogno di un utente come parametro. Quindi potremmo anche avere tutti quei servizi chiamati dall'utente stesso, e semplicemente usare user.GetMeetings(); quando vogliamo quelle riunioni. Questo utente sarebbe in grado di controllare tutto da solo,. isLoggedIn , o. logIn , e molto altro.

Da un lato, questo aspetto è "più semplice" all'esterno, chiamiamo sempre un metodo utente e i nostri viewmodels non conoscono nulla se non un utente. D'altra parte questo sembra proprio un wrapper giant che copre praticamente l'intera applicazione (che si estende oltre gli ospiti e gli ospiti).

Ci sarebbe quel livello utente che fa tutto attraverso l'utente corrente, e tutti quei servizi esisterebbero ancora ma solo l'utente lo chiamerebbe, e stiamo solo girando in circolo perché "l'utente è ovunque comunque, e i servizi sarebbero comunque chiamati ovunque ". Ma l'utente che fa tutto sembra così strettamente legato ai servizi che sembra sbagliato, anche se solo lui lo usa e lo farà sempre.

Ad ogni modo, mi piacerebbe sapere cosa ne pensate voi ragazzi, c'è qualcosa di meglio? C'è uno standard? C'è una risposta sbagliata nelle mie due situazioni? Nota (e questo è importante) che stiamo discutendo solo nel contesto della nostra app, non in generale. Ovviamente se gli utenti dovessero interagire tra loro, se avessi utenti anonimi o molte altre situazioni, questo non funzionerebbe. Ma noi sappiamo che questo rimarrà sempre lo stesso, l'utente sarà sempre necessario per le chiamate al servizio web e ci sarà sempre un solo utente. Sono stato seduto lì ad ascoltarli e sono solo confuso e curioso di avere un feedback esterno su questo.

Non sto parlando di una grande e grande classe di Dio per l'utente. In entrambi i casi tutte le chiamate vengono effettuate in classi di servizi / gestori separati. La grande differenza è la seguente:

  • Caso 1: Il mio modello conosce l'utente corrente e il servizio di cui ha bisogno (es: MeetingService ), e chiede semplicemente al servizio riunione di ottenere tutte le riunioni e gli assegna l'utente corrente come parametro.

  • Caso 2: il mio modello conosce solo l'utente corrente e gli chiede di ottenere tutti i meeting (. GetMyMeetings(); ), senza preoccuparsi di come lo fa. L'utente stesso conosce semplicemente tutti i diversi servizi di cui potrebbe aver bisogno e, in tal caso, chiama il MeetingService e restituisce tutto ciò che è stato chiesto.

Stiamo semplicemente aggiungendo un livello nella nostra gerarchia, in modo che tutti si combinino nell'utente.

Ma in termini di codice, l'utente non diventerà così grande, probabilmente finirà per essere lungo circa 100 righe, comprese le proprietà e tutti i metodi di cui avremo bisogno.

    
posta Gil Sand 01.09.2015 - 12:11
fonte

3 risposte

5

A meno che User non abbia un Service per fare cose da utente, non fare in modo che l'utente faccia finta di essere il contesto / stato generale dell'applicazione.

"Convenienza" e "LOC per classe" non sono principi di progettazione.

Metti a fuoco le tue lezioni in modo preciso. Aderire in modo fanatico al principio della singola responsabilità.

the user won't get that big

irrilevante.

it'll probably end up being about 100 lines long

irrilevante.

including properties and all the methods we'll need.

Violazioni SRP in corso.

There can only be one user logged in at any given time and all calls require a user.

Questo è lo stato che né UserService possono conoscere da soli, separatamente, per così dire. Questo stato è specifico per il più ampio contesto applicativo. Quindi hai bisogno di una o più altre classi - ApplicationContext diciamo, che conosce questo contesto e interroga gli oggetti partecipanti per quello che sanno (io, l'utente, sono loggato per esempio) facendo così ApplicationContext cose.

We're really just adding a layer into our hierarchy, so that they all combine in the user.

"combinare l'utente" non è categoricamente "aggiungere un livello nella nostra gerarchia". L'aggiunta di un livello sarebbe qualcosa come sopra.

    
risposta data 01.09.2015 - 19:00
fonte
4

Vorrei andare con l'approccio Service.GetMeetings (utente u).

Ecco il mio ragionamento.

Nella mia esperienza l'unica differenza tra questi due approcci una volta aggiunti DTO e progetti di hosting per i tuoi servizi è la denominazione.

Se mantieni la logica dell'Utente, l'Utente è equivalente a ciò che sarebbe stato il tuo UserDTO

La tua nuova classe di servizio sembra una funzione extra di "supporto" fino a che non esponi User.GetMeetings () tramite IUser e un resto di hosting / wcf / progetto personale, nel qual caso comunque finirai con un gruppo di classi extra.

Quindi, in generale, Service.GetMeetings (utente u) significa meno codice e più facile riutilizzo del codice. puoi incollare il tuo utente e le tue lezioni in un lib di classe portatile e condividerle con la tua app.

    
risposta data 01.09.2015 - 18:06
fonte
3

Ogni servizio dovrebbe essere autonomo.

La maggior parte degli sviluppatori sa che quando qualcosa è "impostato su pietra" , cambierà su te quando meno te lo aspetti, costringendoti a riprogettare la tua soluzione.

Dovresti sempre progettare le tue soluzioni per essere corrette da un punto di vista tecnologico, anche se ciò rende le cose un po 'più complicate all'inizio.

La separazione delle preoccupazioni è il tuo miglior strumento per impedirti di codificarti in un angolo.

Tra due anni i requisiti potrebbero cambiare e improvvisamente è necessario consentire agli utenti anonimi di creare una riunione (ad esempio, si passa a un modello freemium). Ora devi ri-progettare la tua classe utente per avere un oggetto utente anonimo o devi spostare tutte le chiamate della funzione riunione fuori dall'oggetto Utente, nella posizione corretta nel servizio Meeting.

O si impostano riunioni continue in cui nessuna persona è il creatore della riunione, ora l'oggetto Utente è completamente disaccoppiato dalla creazione di una riunione. Il creatore di una riunione può essere un oggetto aziendale o legato a un oggetto Room.

Puoi sempre aspettarti che i requisiti diventino più complessi e complicati, dovresti pianificare ora.

    
risposta data 01.09.2015 - 15:19
fonte

Leggi altre domande sui tag