2010-02-28 19 views
5

Supponendo che il seguente entità del dominio:Standard Methods vs Estensioni Metodi

public enum Role 
{ 
    User = 0, 
    Moderator = 1, 
    Administrator = 2 
} 

public class User 
{ 
    public string FirstName { get; set; } 
    public string LastName { get; set; } 
    public string Email { get; set; } 
    public Role Role { get; set; } 
} 

ho bisogno di sapere se l'utente può eseguire l'azione "Modifica". Così ho 2 soluzioni:

Creare un metodo CanEdit all'interno dell'entità utente

public class User 
{ 
    public string FirstName { get; set; } 
    public string LastName { get; set; } 
    public string Email { get; set; } 
    public Role Role { get; set; } 

    public bool CanEdit() 
    { 
     return Role == Role.Moderator || Role == Role.Administrator; 
    } 
} 

creare un metodo di estensione CanEdit per il tipo di utente:

public static class UserExtensions 
{ 
    public static bool CanEdit(this User user) 
    { 
     return user.Role == Role.Moderator || user.Role == Role.Administrator; 
    } 
} 

Entrambi soluzione funziona, ma la domanda è QUANDO usi i metodi standard contro i metodi di estensione?

risposta

10

I metodi di estensione sono semplicemente zucchero sintattico per metodi statici semplici e ordinari.

Se si controlla la struttura della classe, è necessario implementare tutte le funzionalità necessarie all'interno della classe. Dove i metodi di estensione sono davvero utili/necessari è se non possiedi la classe che stai cercando di "estendere".

Per questo esempio, penso che dovresti inserire la logica nella classe User. È una funzione logica dell'utente stesso; i consumatori dovrebbero essere in grado di utilizzare il metodo CanEdit() senza dover utilizzare o addirittura conoscere la classe UserExtensions.

+1

+1, inoltre, utilizzare i metodi di estensione su Interfacce è una buona pratica. –

+0

+1. I metodi di estensione sono inoltre preziosi quando si tratta di interfacce. –

+0

@Aaronaught: Ok, sono d'accordo, ma perché Microsoft .NET Framework Team implementa i Metodi di estensioni sulle proprie classi di tipi? Perché non implementare direttamente le funzionalità all'interno delle classi? –

1

L'uso dei metodi di estensione non è molto utile per il loro utilizzo. Se il metodo appartiene alla classe, usalo lì. I metodi di estensione servono per estendere le cose, utilizzarle quando non si ha il controllo sulla classe o per fornire funzionalità a un'interfaccia in cui la funzionalità dovrebbe applicarsi a tutte le classi derivate da tale interfaccia.

1

se non si ha accesso diretto al codice sorgente per la classe si dovrebbe usare metodi estensioni se si ha accesso al codice sorgente non vedo alcun motivo per non usare un metodi standard ...

1

I d'accordo con Aaronaught qui: implementa la tua logica alla vecchia maniera. Il metodo statico potrebbe causare problemi (manca l'uso dell'istruzione e il metodo sembra essere "mancante") lateron.

Qualcosa inerente al modello dovrebbe essere parte delle tue lezioni.

2

Io per lo più d'accordo con la risposta di Aaronaught, ma considerare questo:

Forse il metodo CanEdit() o altri metodi simili (regole di business) potrebbe cambiare più o meno spesso o dipendere da alcuni fattori esterni. O nel tempo, avrai sempre più regole del genere (per preoccupazioni diverse). In tal caso, potresti volerli tenere in un posto diverso, separato dal modello di dominio per assicurarti che il modello di dominio non abbia troppe responsabilità diverse e non debba cambiare molto spesso.

Quindi, un modo può essere quello di implementarli come metodi di estensione, poiché ciò consente di mantenere queste regole aziendali separate dal modello di dominio (ad es. Classe utente), ma il metodo è ancora facilmente individuabile dagli utenti della classe User .

Un altro modo per attuare tali regole commerciali è lo specification pattern, in cui si implementa ciascuna regola come classe separata (specifica-), ad es. dimostrato in this blog post.

+0

@Martin: le classi parziali funzionano bene per mantenere un po 'di codice "in un posto diverso" e tuttavia rimanere parte della classe. –

+0

@ John: pensavo di più ad un assemblaggio separato, scambiabile. – M4N

+0

Continuo a non pensare che userò i metodi di estensione per questo. È più probabile che abbia una classe di regole di business separata che prende l'oggetto business come parametro di costruzione o che ha metodi che considerano l'oggetto business come un parametro. –