Modo OOP per progettare un gestore di gruppi di utenti

3

Va bene. Ho questo modello per modellare che viene fornito in due varianti che sono molto simili. Ho una classe che può essere considerata un "entry point" che chiamerà alcune classi manager a seconda dell'interazione dell'utente. Probabilmente possiamo paragonarlo a una classe controller.

Questa classe dovrebbe consentire all'utente di gestire entrambi i gruppi di utenti o utenti stessi. In entrambi i casi le operazioni sono abbastanza simili, è possibile aggiungere, modificare, rimuovere, visualizzare gruppi e utenti. I gruppi hanno un'altra operazione che consiste nell'aggiungere gli utenti al loro interno. Ecco dove sono bloccato:

La mia idea originale era di modellarla in questo modo:

  1. class User ,
  2. class Group ,
  3. class GroupManager ,
  4. class UserManager ,
  5. class IManager

Tuttavia questo ha il problema di non essere in grado di modellare il fatto che i gruppi devono essere in grado di aggiungere utenti a loro. Se lo metto in IManager, è disponibile per UserManager che non ha senso e lo metto come metodo specifico di GroupManager, quindi non posso avere una singola "interfaccia" che sia meno pulita. Questo mi ha portato a saltare del tutto la classe IManager e avere solo entrambi i gestori, ma poi sembra rozzo e ripetitivo.

Esiste un modello di progettazione adeguato da applicare qui?

TLDR : qual è il modello di progettazione corretto in cui tutti i metodi per gestire un gruppo o utente dovrebbero avere la sensazione di una "interfaccia comune", ma essere comunque in grado di modellare il fatto che i gruppi dovrebbero essere in grado aggiungere utenti a se stessi.

    
posta ApplePie 18.07.2013 - 03:29
fonte

2 risposte

3

Mettere un metodo come AddUser nella classe IManager non è davvero un problema finché l'implementazione di quel metodo in UserManager genera solo un'eccezione (o qualche altro tipo di segnalazione di errore.

Ma se i gruppi e gli utenti sono molto simili dal punto di vista "manager", perché non introdurre una classe base comune per Group e User (diciamo IGroup , poiché un utente può essere visto come un gruppo di una sola persona) e sostituire le due diverse classi di manager con una singola che opera su IGroup oggetti in modo più o meno generico? Ovviamente, IGroup avrà anche bisogno di un metodo AddUser e l'implementazione in User dovrebbe generare un'eccezione (come nel mio suggerimento sopra).

Sono d'accordo anche con @Frank che il nome XXXManager può essere scelto meglio, ma immagino che in realtà tu abbia un nome più espressivo e tu lo abbia scelto qui solo per mantenere generale la tua domanda.

Anche correlati (ma forse di dimensioni eccessive per il tuo caso, quando non hai "gruppi di gruppi" :) il pattern composito .

    
risposta data 18.07.2013 - 08:38
fonte
4

Questo sembra essere un design problematico per alcuni motivi:

  • FooManager è spesso una cattiva idea. Vedi questa domanda su come potrebbe essere un segno di cattivo design. Dopotutto, una UserManager è una classe che fa qualcosa con User oggetti .. ma cosa significa esattamente gestire qui?
  • Principio di responsabilità unica - Il S in SOLID è qualcosa che violi con qualsiasi cosa gestisca un utente di o di gruppo. Per la natura stessa del fare questo o quello il tuo componente / gestore non ha più una sola responsabilità, ma almeno due di essi.
  • Hai già detto che "I gruppi hanno una o più operazioni [sic.] che consiste nell'aggiungere utenti al loro interno", quindi hai una comprensione molto naturale che queste operazioni / metodi appartengono alla classe Group . Prima di iniziare a complicare la progettazione, dovresti innanzitutto fornire una spiegazione del motivo per cui questo semplice approccio diretto non è fattibile nel tuo caso.

Qual è la ragione dietro la tua idea che i metodi, che fanno due cose diverse, dovrebbero avere comunque una "interfaccia comune"? A parte la loro natura molto intuitiva e la comprensione di tutti che è possibile aggiungere un utente a un gruppo, tutto ciò che si progetta su di esso è qualcosa che gli altri non capiranno prontamente. Allora, perché preoccuparsi?

Infine, se davvero hai davvero bisogno di definire quell'interfaccia comune, puoi dare un'occhiata al Pattern di facciata . È destinato a corpi di codice più grandi (come interi pacchetti) e sembra ancora eccessivo per una User e una Group di classe.

    
risposta data 18.07.2013 - 07:21
fonte

Leggi altre domande sui tag