2016-04-14 33 views
5

Ho una classe che richiede un modo per recuperare un valore intero casuale con un massimo. Non voglio che questa classe dipenda da un modo specifico per recuperare quel valore casuale (come system.random). Sarebbe meglio:C# Best practice: utilizzo di un delegato o un'interfaccia come dipendenza di classe

(A) Utilizzare un pubblico delegato (o func)

public delegate int NextRandomInt(int maxValue); 

public class MyClass 
{ 
    public NextRandomInt NextRandomInt { get; set; } 

    public MyClass(NextRandomInt nextRandomInt) 
    { 
     NextRandomInt = nextRandomInt; 
    } 
} 

(B) Utilizzare un pubblico un'interfaccia

public interface IRandomIntProvider 
{ 
    int NextInt(int maxValue); 
} 

public class MyClass 
{ 
    public IRandomIntProvider RandomIntProvider { get; set; } 

    public MyClass(IRandomIntProvider randomIntProvider) 
    { 
     RandomIntProvider = randomIntProvider; 
    } 
} 

(C) Qualcosa altrimenti tutti insieme.

Entrambe le modalità funzionano. Mi sento come se l'utilizzo di un delegato fosse più semplice e più veloce da implementare, ma l'interfaccia è più leggibile e potrebbe essere più semplice quando l'iniezione della dipendenza arriva.

+0

Verificare la [Strategia] (http://www.dofactory.com/net/strategy-design-pattern) modello di progettazione GOF. Potrebbe aiutarti. – Fabjan

risposta

0

Secondo il mio punto di vista (ne sono sicuro) la seconda opzione con interfaccia è la migliore. Questa situazione è un tipico esempio del pattern Strategy.

+0

Perché l'interfaccia è la migliore secondo la tua opinione? E come sono collegate queste due affermazioni? La strategia può essere implementata con tutti i tipi di astrazione, inclusi i delegati, quindi non vedo come la Strategia implichi l'uso di un'interfaccia. –

+0

@ Mr.Putty Ho scritto che è il mio punto di vista :) Preferisco le interfacce in questi esempi perché per l'utilizzo del delegato dovresti creare un metodo in qualche classe (e non vedo come dovrebbe essere chiamata questa classe - 'RandomDelegates '?). E sarà semplicemente più bello creare una piccola interfaccia con una classe specifica. Spero di poterti spiegare la mia idea. – user2216

1

Dipende dalla quantità di lavoro che si desidera implementare utilizzando un delegato o un'interfaccia.

Se l'interfaccia avrà solo uno o due metodi, è possibile utilizzare uno Func per forzare lo stesso comportamento. Altrimenti userei interface s.

Mark Seemann spiegato proprio questo abbastanza bene qui: link

Insomma egli afferma questo:

Quando possibile, preferisco di modellare le mie API con i delegati invece di interfacce di un metodo, dal momento che mi dà maggiore flessibilità e meno codice di infrastruttura.

Ovviamente, questa tecnica funziona solo finché è necessario solo astrarre un singolo metodo. Non appena la tua astrazione necessita di un secondo metodo, dovrai introdurre un'interfaccia corretta o, preferibilmente, una classe di base astratta.

0
  1. Usa interfaccia se si pensa che ci possa essere un'altra implementazione di NextRandomInt() può esistere nel sistema.
  2. Scegliere il delegato se si ritiene che debba essere eseguito come causa di un evento o richiamata.
    Altrimenti, basta andare con un metodo come membro della classe. Spetta a te se desideri che il metodo sia disponibile come metodo instance o static.