Domanda

Ho un piccolo dilemma che forse puoi aiutarmi a risolvere.

Ho lavorato oggi per modificare l'appartenenza di ASP.NET per aggiungere un livello di riferimento indiretto.Fondamentalmente, l'appartenenza di ASP.NET supporta utenti e ruoli, lasciando che tutte le regole di autorizzazione siano basate sull'appartenenza o meno di un utente a un ruolo.

Quello che devo fare è aggiungere il concetto di Funzione, dove un utente apparterrà a un ruolo (o ruoli) e al ruolo saranno associate una o più funzioni, permettendoci di autorizzare un'azione specifica in base all'appartenenza dell'utente ad un ruolo a cui è assegnata una funzione.

Detto questo, il mio problema non ha nulla a che fare con questo, è un problema di progettazione di classi generiche.

Voglio fornire un metodo astratto nella mia classe RoleProvider di base per creare la funzione (e persisterla), ma voglio rendere facoltativo il salvataggio di una descrizione per quella funzione, quindi devo creare il mio metodo CreateFunction con un sovraccarico, uno firma che accetta il nome e l'altra che accetta il nome e la descrizione.

Mi vengono in mente i seguenti scenari:

  1. Crea entrambe le firme con il modificatore astratto.Ciò presenta il problema che l'implementatore potrebbe non rispettare la migliore pratica secondo cui un sovraccarico dovrebbe chiamare l'altro con i parametri normalizzati e la logica dovrebbe essere solo in quello finale (quello con tutti i parametri).Inoltre, non è carino richiedere che entrambi i metodi siano implementati dallo sviluppatore.

  2. Crea il primo come virtuale e il secondo come astratto.Chiama il secondo dal primo, consenti all'implementatore di sovrascrivere il comportamento.Ha lo stesso problema, l'implementatore potrebbe prendere "decisioni sbagliate" quando lo sovrascrive.

  3. Come prima, ma non consentire l'override del primo (rimuovere il modificatore virtuale).Il problema qui è che l'implementatore deve essere consapevole che il metodo potrebbe essere chiamato con una descrizione nulla e deve gestire tale situazione.

Penso che la soluzione migliore sia la terza...

Come viene gestito questo scenario in generale?Quando si progetta una classe astratta che contiene metodi sovraccaricati.Non è così raro, credo...

È stato utile?

Soluzione

Sento che la migliore combinazione di DRYness e forzatura del contratto è la seguente (in pseudocodice):

class Base {
  public final constructor(name) {
    constructor(name, null)
  end

  public abstract constructor(name, description);
}

o, in alternativa:

class Base {
  public abstract constructor(name);

  public final constructor(name, description) {
    constructor(name)
    this.set_description(description)
  }

  private final set_description(description) {
    ...
  }
}

C'è una regola in Java che supporta questa decisione:"non chiamare mai metodi non finali da un costruttore."

Altri suggerimenti

Per rispondere alla prima parte del tuo post, controlla AzMan (Authorization Manager), che, per inciso, è integrato in Windows.Ha la capacità di specificare operazioni che possono essere ricombinate in ruoli o assegnate direttamente agli utenti.

Guardare

Per rispondere alla seconda parte della tua domanda, non utilizzerei una classe Abstract.Invece basta fornire la funzionalità nel costruttore e farla finita.Sembra che tu voglia il comportamento specificato e non vuoi che cambi.Perché forzare i discendenti a fornire l'implementazione.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top