A dio (classe) o no a dio? [duplicare]

1

Sto lavorando a un progetto che richiede diversi utenti nel sistema, tutti con responsabilità che si sovrappongono; abbiamo isolato due possibili modi per affrontare questo problema, ma non siamo sicuri di quale di essi sia il modo più corretto per farlo.

Opzione 1: crea una super classe virtuale per tutte le classi utente da cui ereditare. Questa super-classe avrà un campo booleano per ciascuna delle responsabilità, permettendoci di cambiare a quale delle sottoclassi è responsabile.

  • Pro
    • Una singola classe per tutte le sottoclassi da cui ereditare, che ci consente di attivare le responsabilità tramite i campi booleani
  • Contro:
    • È essenzialmente una classe di Dio, il che significa che ha troppe responsabilità

Opzione 2: crea 19 interfacce, ognuna delle quali rappresenta una delle responsabilità disponibili, e quindi ciascuna delle classi utente eredita da questo pool di interfacce per determinarne le responsabilità.

  • Pro
    • Ci consente di separare le preoccupazioni in diverse interfacce
  • Contro
    • Saremo al di sopra delle nostre interfacce, rendendo difficile tenere traccia di

Quindi qual è il modo migliore per farlo, o forse c'è un modo migliore?

Per elaborare la mia domanda, includo il grafico sottostante; mostra le relazioni tra le diverse parti del sistema e i diversi utenti.

R significa accesso lettura e RW significa accesso lettura + scrittura .

Come puoi vedere è un po 'un casino di attributi di interlacciamento.

    
posta Electric Coffee 19.10.2015 - 10:41
fonte

2 risposte

3

Opzione 3 : crea singoli oggetti corrispondenti a responsabilità specifiche, quindi chiedi a ciascun utente di conservare una raccolta di questi.

La raccolta di responsabilità per un utente conterrà solo le responsabilità assegnate all'utente, cioè non è necessario un oggetto per indicare la mancanza di una responsabilità.

Ti preoccupi che sia "eccessivo" creare 19 classi per 19 responsabilità, ma in realtà è la soluzione più semplice. Se si indica lo stesso con 19 campi booleani sulla classe base, si ha lo stesso numero di entità semantiche, ma un sistema molto più complesso nel complesso, poiché ogni nuova responsabilità aumenta la complessità di tutte le classi utente . Avendo le responsabilità come oggetti separati dall'utente, una nuova responsabilità non influirà affatto sulle classi utente, ma solo sulle parti specifiche del programma che controllano questa specifica responsabilità.

Inoltre, puoi facilmente separare l'assegnazione delle responsabilità in una configurazione. Questo sarebbe abbastanza complicato con l'opzione 1 e impossibile con l'opzione 2.

Nota: se è necessario distinguere tra lettura e lettura / scrittura, è necessario più di 19 campi booleani o 19 interfacce. Per l'opzione 1 hai bisogno di enumerazioni a tre stati piuttosto che di booleani. Per l'opzione 2 sono necessarie 38 interfacce distinte. Per l'opzione 3 puoi avere un flag booleano su ogni responsabilità che indica se è letto o letto / scritto.

    
risposta data 19.10.2015 - 11:08
fonte
3

Opterei per l'opzione 3, uso la composizione.

A seconda di cosa stai facendo con le responsabilità, potresti essere in grado di usare un enumer per loro:

public enum Responsibilities
{
    Responsibility1,
    Responsibility2,
    ...
}

Quindi la tua classe utente potrebbe essere qualcosa del tipo:

public class User
{
    private List<Responsibilities> _responsibilities =
        List<Responsibilities>();

    public void AddResponsibility(Responsibilities responsibility) =>
        _responsibilities.Add(responsibility);

    public bool HasResponsibility(Responsibilities responsibility) =>
        responsibilities.Contains(responsibility);
}

Se la tua logica di necessità dietro ogni responsabilità, sostituisci l'enum con un'interfaccia IResponsibility e fai in modo che ogni classe di responsabilità implementa tale interfaccia.

    
risposta data 19.10.2015 - 11:11
fonte

Leggi altre domande sui tag